From 4220674f115e8bcf2baa20cdb67c36ed766f8a3f Mon Sep 17 00:00:00 2001 From: revoltez Date: Tue, 30 Jul 2024 12:01:07 +0100 Subject: [PATCH 1/8] wip!: create payment channel authorization grants --- Dockerfile | 4 +- {cmd/autoscaler => autoscaler}/main.go | 14 +- cmd/tpodserver/manifest.go | 2 +- cmd/trustedpods/deploy.go | 17 +- cmd/trustedpods/flags.go | 2 + cmd/trustedpods/pod.go | 1 + cmd/trustedpods/sync.go | 4 +- contracts/src/Payment.sol | 49 ++++++ contracts/src/Registry.sol | 2 +- contracts/test/Payment.t.sol | 73 ++++++++ contracts/test/Registry.t.sol | 4 +- pkg/abi-ts/generated.ts | 38 +++++ pkg/abi/Payment.abi.go | 75 +++++++- {cmd => pkg}/autoscaler/server.go | 93 ++++++++-- pkg/constants/constants.go | 8 + pkg/ethereum/client.go | 24 +++ pkg/kubernetes/pods.go | 50 +++++- pkg/proto-ts/pod_pb.ts | 6 + pkg/proto-ts/provision-pod_pb.ts | 12 ++ pkg/proto/pod.pb.go | 14 +- pkg/proto/provision-pod.pb.go | 228 ++++++++++++++----------- pkg/provider/server.go | 5 +- pkg/publisher/connect.go | 22 ++- proto/pod.proto | 1 + proto/provision-pod.proto | 2 + test/e2e/autoscaler/run-test.sh | 11 +- 26 files changed, 617 insertions(+), 144 deletions(-) rename {cmd/autoscaler => autoscaler}/main.go (69%) rename {cmd => pkg}/autoscaler/server.go (68%) create mode 100644 pkg/constants/constants.go diff --git a/Dockerfile b/Dockerfile index f4e2a6be..34931427 100644 --- a/Dockerfile +++ b/Dockerfile @@ -51,8 +51,8 @@ ENTRYPOINT ["tpodserver"] FROM build-common as build-autoscaler -COPY cmd/autoscaler ./cmd/autoscaler -RUN --mount=type=cache,target=/root/.cache/go-build go build -v -o /usr/local/bin/autoscaler ./cmd/autoscaler +COPY autoscaler ./autoscaler +RUN --mount=type=cache,target=/root/.cache/go-build go build -v -o /usr/local/bin/autoscaler ./autoscaler FROM run-common as autoscaler diff --git a/cmd/autoscaler/main.go b/autoscaler/main.go similarity index 69% rename from cmd/autoscaler/main.go rename to autoscaler/main.go index 4244caa0..58a0aecc 100644 --- a/cmd/autoscaler/main.go +++ b/autoscaler/main.go @@ -5,6 +5,7 @@ import ( "log" "net/http" + "github.com/comrade-coop/apocryph/pkg/autoscaler" pbcon "github.com/comrade-coop/apocryph/pkg/proto/protoconnect" tpraft "github.com/comrade-coop/apocryph/pkg/raft" "golang.org/x/net/http2" @@ -13,14 +14,21 @@ import ( func main() { mux := http.NewServeMux() - self, err := tpraft.NewPeer(fmt.Sprintf("/ip4/0.0.0.0/tcp/%v", RAFT_P2P_PORT)) + self, err := tpraft.NewPeer(fmt.Sprintf("/ip4/0.0.0.0/tcp/%v", autoscaler.RAFT_P2P_PORT)) if err != nil { fmt.Println("Failed creating p2p node") return } + fmt.Printf("PEER ID: %v\n", self.ID()) - server := &AutoScalerServer{self: self} - server.mainLoop = setAppGatewayExample + + server, err := autoscaler.NewAutoSalerServer("http://eth-rpc.eth.svc.cluster.local:8545") + if err != nil { + fmt.Println("Failed creating AutoScaler Server") + return + } + + server.MainLoop = autoscaler.SetAppGatewayExample path, handler := pbcon.NewAutoscalerServiceHandler(server) mux.Handle(path, handler) log.Println("Autoscaler RPC Server Started") diff --git a/cmd/tpodserver/manifest.go b/cmd/tpodserver/manifest.go index e78035b5..fc961311 100644 --- a/cmd/tpodserver/manifest.go +++ b/cmd/tpodserver/manifest.go @@ -61,7 +61,7 @@ var applyManifestCmd = &cobra.Command{ response := &pb.ProvisionPodResponse{} namespace := tpk8s.NewTrustedPodsNamespace("tpods-xx", nil) err = tpk8s.RunInNamespaceOrRevert(cmd.Context(), cl, namespace, dryRun, func(cl client.Client) error { - return tpk8s.ApplyPodRequest(cmd.Context(), cl, namespace.ObjectMeta.Name, false, pod, images, secrets, response) + return tpk8s.ApplyPodRequest(cmd.Context(), cl, namespace.ObjectMeta.Name, false, pod, nil, images, secrets, response) }) if err != nil { return err diff --git a/cmd/trustedpods/deploy.go b/cmd/trustedpods/deploy.go index a10aba49..7c09454b 100644 --- a/cmd/trustedpods/deploy.go +++ b/cmd/trustedpods/deploy.go @@ -93,6 +93,11 @@ var deployPodCmd = &cobra.Command{ } configureDeployment(deployment) + if authorize { + fmt.Println("Authorizing ...") + pod.Authorized = true + } + fundsInt, _ := (&big.Int{}).SetString(funds, 10) if fundsInt == nil { return fmt.Errorf("Invalid number passed for funds: %s", funds) @@ -130,7 +135,7 @@ var deployPodCmd = &cobra.Command{ interceptor := pbcon.NewAuthInterceptorClient(deployment, expirationOffset, sign) - var client *publisher.P2pProvisionPodServiceClient + var provisionPodclient *publisher.P2pProvisionPodServiceClient if len(deployment.GetProvider().GetEthereumAddress()) == 0 || deployment.GetProvider().GetLibp2PAddress() == "" { availableProviders, err := fetchAndFilterProviders(ipfs, ethClient) if err != nil { @@ -139,12 +144,12 @@ var deployPodCmd = &cobra.Command{ if len(availableProviders) == 0 { return fmt.Errorf("Failed finding a provider: no available providers found matching filter") } - client, err = publisher.SetFirstConnectingProvider(ipfsp2p, availableProviders, deployment, interceptor) + provisionPodclient, err = publisher.SetFirstConnectingProvider(ipfsp2p, availableProviders, deployment, interceptor) if err != nil { return fmt.Errorf("Failed setting a provider: %w", err) } } else { - client, err = publisher.ConnectToProvider(ipfsp2p, deployment, interceptor) + provisionPodclient, err = publisher.ConnectToProvider(ipfsp2p, deployment, interceptor) if err != nil { return err } @@ -179,7 +184,7 @@ var deployPodCmd = &cobra.Command{ return err } - err = publisher.SendToProvider(cmd.Context(), ipfsp2p, pod, deployment, client) + err = publisher.SendToProvider(cmd.Context(), ipfsp2p, pod, deployment, provisionPodclient, ethClient, publisherAuth) if err != nil { return err } @@ -215,7 +220,7 @@ var deletePodCmd = &cobra.Command{ publisherKey = common.BytesToAddress(deployment.Payment.PublisherAddress).String() } - _, sign, err := ethereum.GetAccountAndSigner(publisherKey, ethClient) + publisherAuth, sign, err := ethereum.GetAccountAndSigner(publisherKey, ethClient) if err != nil { return fmt.Errorf("Could not get ethereum account: %w", err) } @@ -229,7 +234,7 @@ var deletePodCmd = &cobra.Command{ return err } - err = publisher.SendToProvider(cmd.Context(), tpipfs.NewP2pApi(ipfs, ipfsMultiaddr), nil, deployment, client) + err = publisher.SendToProvider(cmd.Context(), tpipfs.NewP2pApi(ipfs, ipfsMultiaddr), nil, deployment, client, ethClient, publisherAuth) if err != nil { return err } diff --git a/cmd/trustedpods/flags.go b/cmd/trustedpods/flags.go index 51c75479..b54ac4f5 100644 --- a/cmd/trustedpods/flags.go +++ b/cmd/trustedpods/flags.go @@ -21,6 +21,7 @@ var providerEthAddress string var registryContractAddress string var tokenContractAddress string var expirationOffset int64 +var authorize bool var uploadFlags = &pflag.FlagSet{} var ipfsApi string @@ -59,6 +60,7 @@ var _ = func() error { deploymentFlags.StringVar(&providerEthAddress, "provider-eth", "", "provider public address") deploymentFlags.Int64Var(&expirationOffset, "token-expiration", 10, "authentication token expires after token-expiration seconds (expired after 10 seconds by default)") deploymentFlags.StringVar(&ipfsApi, "ipfs", "/ip4/127.0.0.1/tcp/5001", "multiaddr where the ipfs/kubo api can be accessed") + deploymentFlags.BoolVar(&authorize, "authorize", false, "Create a key pair for the application and authorize the returned addresses to control the payment channel") uploadFlags.StringVar(&ipfsApi, "ipfs", "/ip4/127.0.0.1/tcp/5001", "multiaddr where the ipfs/kubo api can be accessed") uploadFlags.BoolVar(&uploadImages, "upload-images", true, "upload images") diff --git a/cmd/trustedpods/pod.go b/cmd/trustedpods/pod.go index 6ef61df3..ed829467 100644 --- a/cmd/trustedpods/pod.go +++ b/cmd/trustedpods/pod.go @@ -4,6 +4,7 @@ package main import ( "crypto/sha256" + pb "github.com/comrade-coop/apocryph/pkg/proto" "github.com/ethereum/go-ethereum/common" "github.com/spf13/cobra" diff --git a/cmd/trustedpods/sync.go b/cmd/trustedpods/sync.go index 92db00cb..0acf21f0 100644 --- a/cmd/trustedpods/sync.go +++ b/cmd/trustedpods/sync.go @@ -40,7 +40,7 @@ var syncPodCmd = &cobra.Command{ publisherKey = common.BytesToAddress(deployment.Payment.PublisherAddress).String() } - _, sign, err := ethereum.GetAccountAndSigner(publisherKey, ethClient) + publisherAuth, sign, err := ethereum.GetAccountAndSigner(publisherKey, ethClient) if err != nil { return fmt.Errorf("Could not get ethereum account: %w", err) } @@ -54,7 +54,7 @@ var syncPodCmd = &cobra.Command{ return err } - err = publisher.SendToProvider(cmd.Context(), tpipfs.NewP2pApi(ipfs, ipfsMultiaddr), pod, deployment, client) + err = publisher.SendToProvider(cmd.Context(), tpipfs.NewP2pApi(ipfs, ipfsMultiaddr), pod, deployment, client, ethClient, publisherAuth) if err != nil { return err } diff --git a/contracts/src/Payment.sol b/contracts/src/Payment.sol index fd13ea7a..79b94e21 100644 --- a/contracts/src/Payment.sol +++ b/contracts/src/Payment.sol @@ -13,6 +13,7 @@ contract Payment { error AmountRequired(); error ChannelLocked(); error InsufficientFunds(); + error NotAuthorized(); event UnlockTimerStarted( address indexed publisher, address indexed provider, bytes32 indexed podId, uint256 unlockedAt @@ -30,6 +31,7 @@ contract Payment { uint256 withdrawnByProvider; uint256 unlockTime; // minimum time in seconds needed to unlock the funds uint256 unlockedAt; // time @ unlock + unlockTime + mapping(address => bool) authorized; } // publisher => provider => token => PodID => funds @@ -159,4 +161,51 @@ contract Payment { Channel storage channel = channels[publisher][provider][podId]; return channel.withdrawnByProvider; } + + // authorize other addresses to create subChannels + function authorize(address _authorized, address provider, bytes32 podId) public { + Channel storage channel = channels[msg.sender][provider][podId]; + if (channel.investedByPublisher == 0) revert DoesNotExist(); + channel.authorized[_authorized] = true; + } + + function isAuthorized(address publisher, address provider, bytes32 podId, address _address) + public + view + returns (bool) + { + return channels[publisher][provider][podId].authorized[_address]; + } + + // create a subChannel from a main channel + function createSubChannel( + address publisher, + address provider, + bytes32 podId, + address newProvider, + bytes32 newPodId, + uint256 amount + ) public { + Channel storage channel = channels[publisher][provider][podId]; + // Ensure the channel exists + if (channel.investedByPublisher == 0) revert DoesNotExist(); + + // Check if the caller is authorized + if (!channel.authorized[msg.sender]) revert NotAuthorized(); + + // Ensure there is enough invested by the publisher + if (channel.investedByPublisher < amount) revert InsufficientFunds(); + + // Deduct the amount from the main channel's funds + channel.investedByPublisher -= amount; + + // Create the subChannel for the authorized caller + Channel storage subChannel = channels[msg.sender][newProvider][newPodId]; + + // fund the new sub channel with the deducted amount from the main channel + subChannel.investedByPublisher = amount; + subChannel.unlockTime = channel.unlockTime; // Inherit unlock time from main channel + + emit Deposited(msg.sender, newProvider, newPodId, amount); + } } diff --git a/contracts/src/Registry.sol b/contracts/src/Registry.sol index 98620757..289a80c6 100644 --- a/contracts/src/Registry.sol +++ b/contracts/src/Registry.sol @@ -85,7 +85,7 @@ contract Registry { subscription[msg.sender][tableId] = false; } - function isSubscribed(address provider ,uint256 tableId) external view returns (bool) { + function isSubscribed(address provider, uint256 tableId) external view returns (bool) { return subscription[provider][tableId]; } } diff --git a/contracts/test/Payment.t.sol b/contracts/test/Payment.t.sol index 21711fc5..16d0a273 100644 --- a/contracts/test/Payment.t.sol +++ b/contracts/test/Payment.t.sol @@ -155,4 +155,77 @@ contract PaymentTest is Test { payment.withdrawUnlocked(provider, podId); assertEq(token.balanceOf(publisher), 300); } + + function test_authorize() public { + // Setup + vm.startPrank(publisher); + token.mint(1000); + token.approve(address(payment), 1000); + payment.createChannel(provider, podId, 1, 500); + + // Test authorizing an address + address authorizedAddr = address(0x123); + payment.authorize(authorizedAddr, provider, podId); + + // Verify authorization (we'll need to add a getter function in the contract for this) + assertTrue(payment.isAuthorized(publisher, provider, podId, authorizedAddr)); + + // Test authorizing for non-existent channel + bytes32 nonExistentPodId = keccak256("non-existent"); + vm.expectRevert(Payment.DoesNotExist.selector); + payment.authorize(authorizedAddr, provider, nonExistentPodId); + + vm.stopPrank(); + } + + function test_createSubChannel() public { + // Setup + vm.startPrank(publisher); + // mint 1000 to the caller (publisher) + token.mint(1000); + token.approve(address(payment), 1000); + payment.createChannel(provider, podId, 1, 500); + bytes32 newPodId = bytes32(uint256(1)); + + address authorizedAddr = address(0x123); + payment.authorize(authorizedAddr, provider, podId); + vm.stopPrank(); + + // Test creating a sub-channel + vm.startPrank(authorizedAddr); + address newProvider = address(0x456); + payment.createSubChannel(publisher, provider, podId, newProvider, + newPodId, 200); + + // Verify sub-channel creation + (uint256 investedAmount, uint256 withdrawnAmount, uint256 unlockTime,) = + payment.channels(authorizedAddr, newProvider, newPodId); + assertEq(investedAmount, 200); + assertEq(withdrawnAmount, 0); + assertEq(unlockTime, 1); // should be the same as the main channel's unlock time + + // Verify main channel balance reduction + (uint256 mainChannelBalance,,,) = payment.channels(publisher, provider, podId); + assertEq(mainChannelBalance, 300); + + // Test creating sub-channel with insufficient funds + vm.expectRevert(Payment.InsufficientFunds.selector); + payment.createSubChannel(publisher, provider, podId, newProvider, + newPodId,400); + + // Test creating sub-channel from non-existent main channel + bytes32 nonExistentPodId = keccak256("non-existent"); + vm.expectRevert(Payment.DoesNotExist.selector); + payment.createSubChannel(publisher, provider, nonExistentPodId, + newProvider, newPodId,100); + + // Test creating sub-channel without authorization + vm.stopPrank(); + vm.startPrank(address(0x789)); // Non-authorized address + vm.expectRevert(Payment.NotAuthorized.selector); + payment.createSubChannel(publisher, provider, podId, + newProvider,newPodId, 100); + + vm.stopPrank(); + } } diff --git a/contracts/test/Registry.t.sol b/contracts/test/Registry.t.sol index d8ce0771..ff160e66 100644 --- a/contracts/test/Registry.t.sol +++ b/contracts/test/Registry.t.sol @@ -66,7 +66,7 @@ contract RegistryTest is Test { vm.expectEmit(true, true, false, false, address(registry)); emit Registry.Subscribed(tableId, provider2); registry.subscribe(tableId); - bool subscribed = registry.isSubscribed(provider2,tableId); + bool subscribed = registry.isSubscribed(provider2, tableId); assertEq(subscribed, true); } @@ -78,7 +78,7 @@ contract RegistryTest is Test { bool subscribed = registry.isSubscribed(provider, tableId); assertEq(subscribed, true); registry.unsubscribe(tableId); - subscribed = registry.isSubscribed(provider,tableId); + subscribed = registry.isSubscribed(provider, tableId); assertEq(subscribed, false); } } diff --git a/pkg/abi-ts/generated.ts b/pkg/abi-ts/generated.ts index 084c2b0a..1e25f26f 100644 --- a/pkg/abi-ts/generated.ts +++ b/pkg/abi-ts/generated.ts @@ -179,6 +179,17 @@ export const paymentAbi = [ ], stateMutability: 'nonpayable' }, + { + type: 'function', + inputs: [ + { name: '_authorized', internalType: 'address', type: 'address' }, + { name: 'provider', internalType: 'address', type: 'address' }, + { name: 'podId', internalType: 'bytes32', type: 'bytes32' } + ], + name: 'authorize', + outputs: [], + stateMutability: 'nonpayable' + }, { type: 'function', inputs: [ @@ -228,6 +239,20 @@ export const paymentAbi = [ outputs: [], stateMutability: 'nonpayable' }, + { + type: 'function', + inputs: [ + { name: 'publisher', internalType: 'address', type: 'address' }, + { name: 'provider', internalType: 'address', type: 'address' }, + { name: 'podId', internalType: 'bytes32', type: 'bytes32' }, + { name: 'newProvider', internalType: 'address', type: 'address' }, + { name: 'newPodId', internalType: 'bytes32', type: 'bytes32' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' } + ], + name: 'createSubChannel', + outputs: [], + stateMutability: 'nonpayable' + }, { type: 'function', inputs: [ @@ -239,6 +264,18 @@ export const paymentAbi = [ outputs: [], stateMutability: 'nonpayable' }, + { + type: 'function', + inputs: [ + { name: 'publisher', internalType: 'address', type: 'address' }, + { name: 'provider', internalType: 'address', type: 'address' }, + { name: 'podId', internalType: 'bytes32', type: 'bytes32' }, + { name: '_address', internalType: 'address', type: 'address' } + ], + name: 'isAuthorized', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view' + }, { type: 'function', inputs: [], @@ -484,6 +521,7 @@ export const paymentAbi = [ name: 'InsufficientBalance' }, { type: 'error', inputs: [], name: 'InsufficientFunds' }, + { type: 'error', inputs: [], name: 'NotAuthorized' }, { type: 'error', inputs: [{ name: 'token', internalType: 'address', type: 'address' }], diff --git a/pkg/abi/Payment.abi.go b/pkg/abi/Payment.abi.go index 58f4e3c2..c6fb17e2 100644 --- a/pkg/abi/Payment.abi.go +++ b/pkg/abi/Payment.abi.go @@ -31,7 +31,7 @@ var ( // PaymentMetaData contains all meta data concerning the Payment contract. var PaymentMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_token\",\"type\":\"address\",\"internalType\":\"contractIERC20\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"available\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"channels\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"investedByPublisher\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"withdrawnByProvider\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"unlockTime\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"unlockedAt\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"closeChannel\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"createChannel\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"unlockTime\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"initialAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"deposit\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"token\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIERC20\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"unlock\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdraw\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"transferAddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawUnlocked\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawUpTo\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"totalWithdrawAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"transferAddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawn\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"ChannelClosed\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ChannelCreated\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Deposited\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"depositAmount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"UnlockTimerStarted\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"unlockedAt\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unlocked\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"unlockedAmount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Withdrawn\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"withdrawnAmount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AddressEmptyCode\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"AlreadyExists\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AmountRequired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ChannelLocked\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"DoesNotExist\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"FailedCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InsufficientBalance\",\"inputs\":[{\"name\":\"balance\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"needed\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"InsufficientFunds\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SafeERC20FailedOperation\",\"inputs\":[{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"address\"}]}]", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_token\",\"type\":\"address\",\"internalType\":\"contractIERC20\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"authorize\",\"inputs\":[{\"name\":\"_authorized\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"available\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"channels\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"investedByPublisher\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"withdrawnByProvider\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"unlockTime\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"unlockedAt\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"closeChannel\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"createChannel\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"unlockTime\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"initialAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"createSubChannel\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"newProvider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"newPodId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"deposit\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isAuthorized\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_address\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"token\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIERC20\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"unlock\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdraw\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"transferAddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawUnlocked\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawUpTo\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"totalWithdrawAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"transferAddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawn\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"ChannelClosed\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ChannelCreated\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Deposited\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"depositAmount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"UnlockTimerStarted\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"unlockedAt\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unlocked\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"unlockedAmount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Withdrawn\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"withdrawnAmount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AddressEmptyCode\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"AlreadyExists\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AmountRequired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ChannelLocked\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"DoesNotExist\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"FailedCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InsufficientBalance\",\"inputs\":[{\"name\":\"balance\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"needed\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"InsufficientFunds\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotAuthorized\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SafeERC20FailedOperation\",\"inputs\":[{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"address\"}]}]", } // PaymentABI is the input ABI used to generate the binding from. @@ -266,6 +266,37 @@ func (_Payment *PaymentCallerSession) Channels(arg0 common.Address, arg1 common. return _Payment.Contract.Channels(&_Payment.CallOpts, arg0, arg1, arg2) } +// IsAuthorized is a free data retrieval call binding the contract method 0x9a99b662. +// +// Solidity: function isAuthorized(address publisher, address provider, bytes32 podId, address _address) view returns(bool) +func (_Payment *PaymentCaller) IsAuthorized(opts *bind.CallOpts, publisher common.Address, provider common.Address, podId [32]byte, _address common.Address) (bool, error) { + var out []interface{} + err := _Payment.contract.Call(opts, &out, "isAuthorized", publisher, provider, podId, _address) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsAuthorized is a free data retrieval call binding the contract method 0x9a99b662. +// +// Solidity: function isAuthorized(address publisher, address provider, bytes32 podId, address _address) view returns(bool) +func (_Payment *PaymentSession) IsAuthorized(publisher common.Address, provider common.Address, podId [32]byte, _address common.Address) (bool, error) { + return _Payment.Contract.IsAuthorized(&_Payment.CallOpts, publisher, provider, podId, _address) +} + +// IsAuthorized is a free data retrieval call binding the contract method 0x9a99b662. +// +// Solidity: function isAuthorized(address publisher, address provider, bytes32 podId, address _address) view returns(bool) +func (_Payment *PaymentCallerSession) IsAuthorized(publisher common.Address, provider common.Address, podId [32]byte, _address common.Address) (bool, error) { + return _Payment.Contract.IsAuthorized(&_Payment.CallOpts, publisher, provider, podId, _address) +} + // Token is a free data retrieval call binding the contract method 0xfc0c546a. // // Solidity: function token() view returns(address) @@ -328,6 +359,27 @@ func (_Payment *PaymentCallerSession) Withdrawn(publisher common.Address, provid return _Payment.Contract.Withdrawn(&_Payment.CallOpts, publisher, provider, podId) } +// Authorize is a paid mutator transaction binding the contract method 0xc970584a. +// +// Solidity: function authorize(address _authorized, address provider, bytes32 podId) returns() +func (_Payment *PaymentTransactor) Authorize(opts *bind.TransactOpts, _authorized common.Address, provider common.Address, podId [32]byte) (*types.Transaction, error) { + return _Payment.contract.Transact(opts, "authorize", _authorized, provider, podId) +} + +// Authorize is a paid mutator transaction binding the contract method 0xc970584a. +// +// Solidity: function authorize(address _authorized, address provider, bytes32 podId) returns() +func (_Payment *PaymentSession) Authorize(_authorized common.Address, provider common.Address, podId [32]byte) (*types.Transaction, error) { + return _Payment.Contract.Authorize(&_Payment.TransactOpts, _authorized, provider, podId) +} + +// Authorize is a paid mutator transaction binding the contract method 0xc970584a. +// +// Solidity: function authorize(address _authorized, address provider, bytes32 podId) returns() +func (_Payment *PaymentTransactorSession) Authorize(_authorized common.Address, provider common.Address, podId [32]byte) (*types.Transaction, error) { + return _Payment.Contract.Authorize(&_Payment.TransactOpts, _authorized, provider, podId) +} + // CloseChannel is a paid mutator transaction binding the contract method 0x9e4ebce5. // // Solidity: function closeChannel(address provider, bytes32 podId) returns() @@ -370,6 +422,27 @@ func (_Payment *PaymentTransactorSession) CreateChannel(provider common.Address, return _Payment.Contract.CreateChannel(&_Payment.TransactOpts, provider, podId, unlockTime, initialAmount) } +// CreateSubChannel is a paid mutator transaction binding the contract method 0x67ca76a6. +// +// Solidity: function createSubChannel(address publisher, address provider, bytes32 podId, address newProvider, bytes32 newPodId, uint256 amount) returns() +func (_Payment *PaymentTransactor) CreateSubChannel(opts *bind.TransactOpts, publisher common.Address, provider common.Address, podId [32]byte, newProvider common.Address, newPodId [32]byte, amount *big.Int) (*types.Transaction, error) { + return _Payment.contract.Transact(opts, "createSubChannel", publisher, provider, podId, newProvider, newPodId, amount) +} + +// CreateSubChannel is a paid mutator transaction binding the contract method 0x67ca76a6. +// +// Solidity: function createSubChannel(address publisher, address provider, bytes32 podId, address newProvider, bytes32 newPodId, uint256 amount) returns() +func (_Payment *PaymentSession) CreateSubChannel(publisher common.Address, provider common.Address, podId [32]byte, newProvider common.Address, newPodId [32]byte, amount *big.Int) (*types.Transaction, error) { + return _Payment.Contract.CreateSubChannel(&_Payment.TransactOpts, publisher, provider, podId, newProvider, newPodId, amount) +} + +// CreateSubChannel is a paid mutator transaction binding the contract method 0x67ca76a6. +// +// Solidity: function createSubChannel(address publisher, address provider, bytes32 podId, address newProvider, bytes32 newPodId, uint256 amount) returns() +func (_Payment *PaymentTransactorSession) CreateSubChannel(publisher common.Address, provider common.Address, podId [32]byte, newProvider common.Address, newPodId [32]byte, amount *big.Int) (*types.Transaction, error) { + return _Payment.Contract.CreateSubChannel(&_Payment.TransactOpts, publisher, provider, podId, newProvider, newPodId, amount) +} + // Deposit is a paid mutator transaction binding the contract method 0xeb2243f8. // // Solidity: function deposit(address provider, bytes32 podId, uint256 amount) returns() diff --git a/cmd/autoscaler/server.go b/pkg/autoscaler/server.go similarity index 68% rename from cmd/autoscaler/server.go rename to pkg/autoscaler/server.go index e41195c7..2b3e1720 100644 --- a/cmd/autoscaler/server.go +++ b/pkg/autoscaler/server.go @@ -1,18 +1,26 @@ -package main +package autoscaler import ( "context" "fmt" "log" + "math/big" "net/http" "net/url" + "os" "strings" "time" "connectrpc.com/connect" + "github.com/comrade-coop/apocryph/pkg/abi" + "github.com/comrade-coop/apocryph/pkg/constants" + "github.com/comrade-coop/apocryph/pkg/ethereum" pb "github.com/comrade-coop/apocryph/pkg/proto" pbcon "github.com/comrade-coop/apocryph/pkg/proto/protoconnect" tpraft "github.com/comrade-coop/apocryph/pkg/raft" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" "github.com/hashicorp/raft" "github.com/libp2p/go-libp2p/core/host" "github.com/libp2p/go-libp2p/core/peer" @@ -24,13 +32,23 @@ const RAFT_PATH = "" type AutoScalerServer struct { pbcon.UnimplementedAutoscalerServiceHandler - node *tpraft.RaftNode - store *tpraft.KVStore - peers []string - started bool - self host.Host - nodeGateway string - mainLoop func(*AutoScalerServer) + node *tpraft.RaftNode + store *tpraft.KVStore + peers []string + started bool + self host.Host + nodeGateway string + ChannelManager *PaymentChannelManager + MainLoop func(*AutoScalerServer) +} + +type PaymentChannelManager struct { + Publisher common.Address + Provider common.Address + PodId common.Hash + EthClient *ethclient.Client + Transactor *bind.TransactOpts + Payment *abi.Payment } func (s *AutoScalerServer) TriggerNode(c context.Context, req *connect.Request[pb.ConnectClusterRequest]) (*connect.Response[pb.TriggerNodeResponse], error) { @@ -42,6 +60,50 @@ func (s *AutoScalerServer) TriggerNode(c context.Context, req *connect.Request[p return connect.NewResponse(&pb.TriggerNodeResponse{PeerID: s.self.ID().String()}), nil } +func NewAutoSalerServer(ethereumRpc string) (*AutoScalerServer, error) { + + ethClient, err := ethereum.GetClient(ethereumRpc) + if err != nil { + return nil, err + } + + key := os.Getenv(constants.PRIVATE_KEY) + paymentAddress := common.HexToAddress(os.Getenv(constants.PAYMENT_ADDR_KEY)) + publisherAddress := common.HexToAddress(os.Getenv(constants.PUBLISHER_ADDR_KEY)) + providerAddress := common.HexToAddress(os.Getenv(constants.PROVIDER_ADDR_KEY)) + podId := common.BytesToHash([]byte(os.Getenv(constants.POD_ID_KEY))) + + log.Printf("ENV Variables: Payment_Address: %v, Publisher Address: %v, ProviderAddress: %v, podId: %v\n", paymentAddress, publisherAddress, providerAddress, podId) + + privateKey, err := ethereum.DecodePrivateKey(key) + + chainID, err := ethClient.ChainID(context.Background()) + if err != nil { + return nil, err + } + + transactor, err := bind.NewKeyedTransactorWithChainID(privateKey, chainID) + if err != nil { + return nil, err + } + + payment, err := abi.NewPayment(paymentAddress, ethClient) + if err != nil { + return nil, err + } + + return &AutoScalerServer{ + ChannelManager: &PaymentChannelManager{ + Publisher: publisherAddress, + Provider: providerAddress, + PodId: podId, + EthClient: ethClient, + Transactor: transactor, + Payment: payment, + }, + }, nil +} + func (s *AutoScalerServer) BoostrapCluster(req *connect.Request[pb.ConnectClusterRequest]) error { peerIDs, err := s.FetchPeerIDsFromServers(req) @@ -149,14 +211,14 @@ func (s *AutoScalerServer) waitLeaderElection(timeout uint32) error { case raft.RaftState: if leaderAddr, _ := s.node.Raft.LeaderWithID(); leaderAddr != "" { fmt.Printf("Leader Elected: %v\n", leaderAddr) - go s.mainLoop(s) + go s.MainLoop(s) return nil } } case <-ticker.C: if leaderAddr, _ := s.node.Raft.LeaderWithID(); leaderAddr != "" { fmt.Printf("Leader Elected: %v\n", leaderAddr) - go s.mainLoop(s) + go s.MainLoop(s) return nil } case <-timeoutCh: @@ -176,9 +238,14 @@ func (s *AutoScalerServer) watchNewStates() { } } -// example of main loop setting the value of a test domain with the current node -// gateway every 5 seconds -func setAppGatewayExample(s *AutoScalerServer) { +// example of main loop creating a subchannel, then setting the value of a test domain +// with the current node gateway every 10 seconds +func SetAppGatewayExample(s *AutoScalerServer) { + tx, err := s.ChannelManager.Payment.CreateSubChannel(s.ChannelManager.Transactor, s.ChannelManager.Publisher, s.ChannelManager.Provider, s.ChannelManager.PodId, s.ChannelManager.Provider, s.ChannelManager.PodId, big.NewInt(500)) + if err != nil { + log.Printf("Failed to create subchannel: %v\n", err) + } + log.Printf("Sub Channel Created Succefully, TX HASH: %v\n", tx.Hash()) log.Println("Starting Main Loop:") for { if s.node.Raft.State() == raft.Leader { diff --git a/pkg/constants/constants.go b/pkg/constants/constants.go new file mode 100644 index 00000000..1a7ff78d --- /dev/null +++ b/pkg/constants/constants.go @@ -0,0 +1,8 @@ +package constants + +const PRIVATE_KEY = "PRIVATE_KEY" +const PUBLIC_ADDRESS_KEY = "PUBLIC_ADDRESS" +const PAYMENT_ADDR_KEY = "PAYMENT_ADDRESS" +const PUBLISHER_ADDR_KEY = "PUBLISHER_ADDRESS" +const PROVIDER_ADDR_KEY = "PROVIDER_ADDRESS" +const POD_ID_KEY = "POD_ID" diff --git a/pkg/ethereum/client.go b/pkg/ethereum/client.go index 8418c01c..5be485fd 100644 --- a/pkg/ethereum/client.go +++ b/pkg/ethereum/client.go @@ -4,6 +4,9 @@ package ethereum import ( "context" + "crypto/ecdsa" + "crypto/x509" + "encoding/pem" "fmt" "strings" @@ -123,3 +126,24 @@ func GetAccountAndSigner(accountString string, client *ethclient.Client) (*bind. return nil, nil, fmt.Errorf("Account %s not found in keystore %s", accountAddress, uri) } } + +// Encode private key +func EncodePrivateKey(privateKey *ecdsa.PrivateKey) (string, error) { + x509Encoded, err := x509.MarshalECPrivateKey(privateKey) + if err != nil { + return "", err + } + pemEncoded := pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: x509Encoded}) + return string(pemEncoded), nil +} + +// Decode private key +func DecodePrivateKey(pemEncoded string) (*ecdsa.PrivateKey, error) { + block, _ := pem.Decode([]byte(pemEncoded)) + if block == nil { + return nil, fmt.Errorf("Could decode Pem Encoded key") + } + x509Encoded := block.Bytes + privateKey, err := x509.ParseECPrivateKey(x509Encoded) + return privateKey, err +} diff --git a/pkg/kubernetes/pods.go b/pkg/kubernetes/pods.go index 19c564e9..d3a970da 100644 --- a/pkg/kubernetes/pods.go +++ b/pkg/kubernetes/pods.go @@ -4,10 +4,17 @@ package kubernetes import ( "context" + "crypto/ecdsa" + "crypto/rand" "fmt" "strings" + "github.com/comrade-coop/apocryph/pkg/constants" + "github.com/comrade-coop/apocryph/pkg/ethereum" pb "github.com/comrade-coop/apocryph/pkg/proto" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/crypto/secp256k1" kedahttpv1alpha1 "github.com/kedacore/http-add-on/operator/apis/http/v1alpha1" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -18,6 +25,9 @@ import ( type FetchSecret func(cid []byte) (map[string][]byte, error) +const PRIVATE_KEY = "PRIVATE_KEY" +const PUBLIC_ADDRESS = "PUBLIC_ADDRESS" + func updateOrCreate(ctx context.Context, resourceName, kind, namespace string, resource interface{}, client k8cl.Client, update bool) error { if update { key := &k8cl.ObjectKey{ @@ -59,6 +69,7 @@ func ApplyPodRequest( namespace string, update bool, podManifest *pb.Pod, + paymentChannel *pb.PaymentChannel, images map[string]string, secrets map[string][]byte, response *pb.ProvisionPodResponse, @@ -89,6 +100,23 @@ func ApplyPodRequest( }, }, } + var privateKey *ecdsa.PrivateKey + var address common.Address + + if podManifest.Authorized == true { + // create the keypair that will be accessible for all pods + var err error + privateKey, err = ecdsa.GenerateKey(secp256k1.S256(), rand.Reader) + if err != nil { + return fmt.Errorf("Could not create private key for the application") + } + + // Ensure the public key is valid before getting the address + if privateKey == nil || privateKey.PublicKey.X == nil || privateKey.PublicKey.Y == nil { + return fmt.Errorf("Generated an invalid public key") + } + address = crypto.PubkeyToAddress(privateKey.PublicKey) + } podTemplate := &deployment.Spec.Template @@ -101,14 +129,34 @@ func ApplyPodRequest( containerSpec := corev1.Container{ Name: container.Name, Image: images[container.Name], - ImagePullPolicy: corev1.PullNever, + ImagePullPolicy: corev1.PullNever, // make sure images are pulled localy Command: container.Entrypoint, Args: container.Command, WorkingDir: container.WorkingDir, } + + if podManifest.Authorized { + + key, err := ethereum.EncodePrivateKey(privateKey) + if err != nil { + return err + } + containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: constants.PRIVATE_KEY, Value: key}) + // save as hex to parse later as hex + containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: constants.PAYMENT_ADDR_KEY, Value: common.BytesToAddress(paymentChannel.ContractAddress).Hex()}) + containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: constants.PUBLISHER_ADDR_KEY, Value: common.BytesToAddress(paymentChannel.PublisherAddress).Hex()}) + containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: constants.PROVIDER_ADDR_KEY, Value: common.BytesToAddress(paymentChannel.ProviderAddress).Hex()}) + containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: constants.POD_ID_KEY, Value: string(paymentChannel.PodID)}) + containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: constants.PRIVATE_KEY, Value: key}) + containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: constants.PUBLIC_ADDRESS_KEY, Value: address.Hex()}) + + response.PubAddress = address.Hex() + } + for field, value := range container.Env { containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: field, Value: value}) } + for _, port := range container.Ports { portName := fmt.Sprintf("p%d-%d", cIdx, port.ContainerPort) containerSpec.Ports = append(containerSpec.Ports, corev1.ContainerPort{ diff --git a/pkg/proto-ts/pod_pb.ts b/pkg/proto-ts/pod_pb.ts index 665a149c..03ec0002 100644 --- a/pkg/proto-ts/pod_pb.ts +++ b/pkg/proto-ts/pod_pb.ts @@ -27,6 +27,11 @@ export class Pod extends Message { */ replicas?: Replicas; + /** + * @generated from field: bool authorized = 4; + */ + authorized = false; + constructor(data?: PartialMessage) { super(); proto3.util.initPartial(data, this); @@ -38,6 +43,7 @@ export class Pod extends Message { { no: 1, name: "containers", kind: "message", T: Container, repeated: true }, { no: 2, name: "volumes", kind: "message", T: Volume, repeated: true }, { no: 3, name: "replicas", kind: "message", T: Replicas }, + { no: 4, name: "authorized", kind: "scalar", T: 8 /* ScalarType.BOOL */ }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): Pod { diff --git a/pkg/proto-ts/provision-pod_pb.ts b/pkg/proto-ts/provision-pod_pb.ts index 50289960..60238efe 100644 --- a/pkg/proto-ts/provision-pod_pb.ts +++ b/pkg/proto-ts/provision-pod_pb.ts @@ -135,6 +135,11 @@ export class UpdatePodRequest extends Message { */ pod?: Pod; + /** + * @generated from field: apocryph.proto.v0.provisionPod.PaymentChannel payment = 2; + */ + payment?: PaymentChannel; + constructor(data?: PartialMessage) { super(); proto3.util.initPartial(data, this); @@ -144,6 +149,7 @@ export class UpdatePodRequest extends Message { static readonly typeName = "apocryph.proto.v0.provisionPod.UpdatePodRequest"; static readonly fields: FieldList = proto3.util.newFieldList(() => [ { no: 1, name: "pod", kind: "message", T: Pod }, + { no: 2, name: "payment", kind: "message", T: PaymentChannel }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): UpdatePodRequest { @@ -286,6 +292,11 @@ export class ProvisionPodResponse extends Message { */ namespace = ""; + /** + * @generated from field: string pubAddress = 4; + */ + pubAddress = ""; + constructor(data?: PartialMessage) { super(); proto3.util.initPartial(data, this); @@ -297,6 +308,7 @@ export class ProvisionPodResponse extends Message { { no: 1, name: "error", kind: "scalar", T: 9 /* ScalarType.STRING */ }, { no: 2, name: "addresses", kind: "message", T: ProvisionPodResponse_ExposedHostPort, repeated: true }, { no: 3, name: "namespace", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 4, name: "pubAddress", kind: "scalar", T: 9 /* ScalarType.STRING */ }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): ProvisionPodResponse { diff --git a/pkg/proto/pod.pb.go b/pkg/proto/pod.pb.go index dd8ec015..cfa69d68 100644 --- a/pkg/proto/pod.pb.go +++ b/pkg/proto/pod.pb.go @@ -126,6 +126,7 @@ type Pod struct { Containers []*Container `protobuf:"bytes,1,rep,name=containers,proto3" json:"containers,omitempty"` Volumes []*Volume `protobuf:"bytes,2,rep,name=volumes,proto3" json:"volumes,omitempty"` Replicas *Replicas `protobuf:"bytes,3,opt,name=replicas,proto3" json:"replicas,omitempty"` + Authorized bool `protobuf:"varint,4,opt,name=authorized,proto3" json:"authorized,omitempty"` } func (x *Pod) Reset() { @@ -181,6 +182,13 @@ func (x *Pod) GetReplicas() *Replicas { return nil } +func (x *Pod) GetAuthorized() bool { + if x != nil { + return x.Authorized + } + return false +} + type Container struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -959,7 +967,7 @@ var File_pod_proto protoreflect.FileDescriptor var file_pod_proto_rawDesc = []byte{ 0x0a, 0x09, 0x70, 0x6f, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x15, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, - 0x6f, 0x64, 0x22, 0xbd, 0x01, 0x0a, 0x03, 0x50, 0x6f, 0x64, 0x12, 0x40, 0x0a, 0x0a, 0x63, 0x6f, + 0x6f, 0x64, 0x22, 0xdd, 0x01, 0x0a, 0x03, 0x50, 0x6f, 0x64, 0x12, 0x40, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, @@ -971,7 +979,9 @@ var file_pod_proto_rawDesc = []byte{ 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x52, 0x08, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x73, 0x22, 0xf4, 0x06, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x61, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, + 0x65, 0x64, 0x22, 0xf4, 0x06, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3c, 0x0a, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, diff --git a/pkg/proto/provision-pod.pb.go b/pkg/proto/provision-pod.pb.go index 0c19b3c5..48576cc8 100644 --- a/pkg/proto/provision-pod.pb.go +++ b/pkg/proto/provision-pod.pb.go @@ -175,7 +175,8 @@ type UpdatePodRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Pod *Pod `protobuf:"bytes,1,opt,name=pod,proto3" json:"pod,omitempty"` + Pod *Pod `protobuf:"bytes,1,opt,name=pod,proto3" json:"pod,omitempty"` + Payment *PaymentChannel `protobuf:"bytes,2,opt,name=payment,proto3" json:"payment,omitempty"` } func (x *UpdatePodRequest) Reset() { @@ -217,6 +218,13 @@ func (x *UpdatePodRequest) GetPod() *Pod { return nil } +func (x *UpdatePodRequest) GetPayment() *PaymentChannel { + if x != nil { + return x.Payment + } + return nil +} + type UpdatePodResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -356,9 +364,10 @@ type ProvisionPodResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Error string `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` - Addresses []*ProvisionPodResponse_ExposedHostPort `protobuf:"bytes,2,rep,name=addresses,proto3" json:"addresses,omitempty"` - Namespace string `protobuf:"bytes,3,opt,name=namespace,proto3" json:"namespace,omitempty"` + Error string `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` + Addresses []*ProvisionPodResponse_ExposedHostPort `protobuf:"bytes,2,rep,name=addresses,proto3" json:"addresses,omitempty"` + Namespace string `protobuf:"bytes,3,opt,name=namespace,proto3" json:"namespace,omitempty"` + PubAddress string `protobuf:"bytes,4,opt,name=pubAddress,proto3" json:"pubAddress,omitempty"` } func (x *ProvisionPodResponse) Reset() { @@ -414,6 +423,13 @@ func (x *ProvisionPodResponse) GetNamespace() string { return "" } +func (x *ProvisionPodResponse) GetPubAddress() string { + if x != nil { + return x.PubAddress + } + return "" +} + type PodLogRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -663,97 +679,104 @@ var file_provision_pod_proto_rawDesc = []byte{ 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x40, 0x0a, 0x10, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x50, 0x6f, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2c, 0x0a, - 0x03, 0x70, 0x6f, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x61, 0x70, 0x6f, - 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, - 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x52, 0x03, 0x70, 0x6f, 0x64, 0x22, 0x43, 0x0a, 0x11, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x22, 0xc0, 0x01, 0x0a, 0x0e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x68, 0x61, 0x6e, - 0x6e, 0x65, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x12, 0x28, 0x0a, - 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, - 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x70, 0x75, 0x62, 0x6c, 0x69, - 0x73, 0x68, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x10, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x12, 0x28, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x41, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, - 0x05, 0x70, 0x6f, 0x64, 0x49, 0x44, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x70, 0x6f, - 0x64, 0x49, 0x44, 0x22, 0xab, 0x02, 0x0a, 0x14, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, - 0x6e, 0x50, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x12, 0x62, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x44, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, - 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, - 0x50, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x45, 0x78, 0x70, 0x6f, - 0x73, 0x65, 0x64, 0x48, 0x6f, 0x73, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x09, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x1a, 0x7b, 0x0a, 0x0f, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x48, - 0x6f, 0x73, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6d, 0x75, 0x6c, 0x74, 0x69, - 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x75, 0x6c, 0x74, - 0x69, 0x61, 0x64, 0x64, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x50, 0x6f, 0x72, - 0x74, 0x22, 0x35, 0x0a, 0x0d, 0x50, 0x6f, 0x64, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x56, 0x0a, 0x0e, 0x50, 0x6f, 0x64, 0x4c, - 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x08, 0x6c, 0x6f, - 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x61, - 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, - 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x2e, 0x4c, 0x6f, - 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6c, 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x22, 0x7c, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x32, 0x0a, 0x14, - 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x55, 0x6e, 0x69, 0x78, 0x45, - 0x70, 0x6f, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x14, 0x4e, 0x61, 0x6e, 0x6f, - 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x55, 0x6e, 0x69, 0x78, 0x45, 0x70, 0x6f, 0x63, 0x68, - 0x12, 0x10, 0x0a, 0x03, 0x6c, 0x6f, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6c, - 0x6f, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, - 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x32, 0xe6, - 0x03, 0x0a, 0x13, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x79, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, - 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x12, 0x33, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, + 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x8a, 0x01, 0x0a, 0x10, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2c, + 0x0a, 0x03, 0x70, 0x6f, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x61, 0x70, + 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, + 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x52, 0x03, 0x70, 0x6f, 0x64, 0x12, 0x48, 0x0a, 0x07, + 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, + 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, + 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x2e, 0x50, + 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x07, 0x70, + 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x43, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x50, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xc0, 0x01, 0x0a, 0x0e, + 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x18, + 0x0a, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x12, 0x28, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x61, 0x63, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x70, 0x75, + 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x28, + 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x6f, 0x64, 0x49, + 0x44, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x70, 0x6f, 0x64, 0x49, 0x44, 0x22, 0xcb, + 0x02, 0x0a, 0x14, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x62, 0x0a, + 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x44, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, + 0x64, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x48, 0x6f, + 0x73, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, + 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, + 0x1e, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x75, 0x62, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x1a, + 0x7b, 0x0a, 0x0f, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x48, 0x6f, 0x73, 0x74, 0x50, 0x6f, + 0x72, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x61, 0x64, 0x64, 0x72, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x61, 0x64, 0x64, 0x72, + 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x50, 0x6f, 0x72, 0x74, 0x22, 0x35, 0x0a, 0x0d, + 0x50, 0x6f, 0x64, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, + 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4e, + 0x61, 0x6d, 0x65, 0x22, 0x56, 0x0a, 0x0e, 0x50, 0x6f, 0x64, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x08, 0x6c, 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, + 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x2e, 0x4c, 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x08, 0x6c, 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x22, 0x7c, 0x0a, 0x08, 0x4c, + 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x32, 0x0a, 0x14, 0x4e, 0x61, 0x6e, 0x6f, 0x73, + 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x55, 0x6e, 0x69, 0x78, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x14, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, + 0x64, 0x73, 0x55, 0x6e, 0x69, 0x78, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x6c, + 0x6f, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6c, 0x6f, 0x67, 0x12, 0x16, 0x0a, + 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x32, 0xe6, 0x03, 0x0a, 0x13, 0x50, 0x72, + 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0x79, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, + 0x64, 0x12, 0x33, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, + 0x6f, 0x64, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, - 0x6e, 0x50, 0x6f, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x61, 0x70, + 0x6e, 0x50, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x73, 0x0a, 0x09, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x64, 0x12, 0x30, 0x2e, 0x61, 0x70, 0x6f, 0x63, + 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x50, 0x6f, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x73, 0x0a, 0x09, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x64, 0x12, 0x30, + 0x65, 0x12, 0x70, 0x0a, 0x09, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x64, 0x12, 0x30, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x2e, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x34, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x31, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, - 0x64, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x70, 0x0a, 0x09, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x50, 0x6f, 0x64, 0x12, 0x30, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, - 0x6e, 0x50, 0x6f, 0x64, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x64, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, - 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x64, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6d, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x50, - 0x6f, 0x64, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x2d, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, - 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, - 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x4c, 0x6f, 0x67, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, - 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6d, 0x72, 0x61, 0x64, 0x65, 0x2d, 0x63, 0x6f, - 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2f, 0x70, 0x6b, 0x67, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x64, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x6d, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x64, 0x4c, 0x6f, 0x67, + 0x73, 0x12, 0x2d, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, + 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2e, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, + 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x30, 0x01, 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x63, 0x6f, 0x6d, 0x72, 0x61, 0x64, 0x65, 0x2d, 0x63, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, + 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -787,21 +810,22 @@ var file_provision_pod_proto_depIdxs = []int32{ 11, // 0: apocryph.proto.v0.provisionPod.ProvisionPodRequest.pod:type_name -> apocryph.proto.v0.pod.Pod 5, // 1: apocryph.proto.v0.provisionPod.ProvisionPodRequest.payment:type_name -> apocryph.proto.v0.provisionPod.PaymentChannel 11, // 2: apocryph.proto.v0.provisionPod.UpdatePodRequest.pod:type_name -> apocryph.proto.v0.pod.Pod - 10, // 3: apocryph.proto.v0.provisionPod.ProvisionPodResponse.addresses:type_name -> apocryph.proto.v0.provisionPod.ProvisionPodResponse.ExposedHostPort - 9, // 4: apocryph.proto.v0.provisionPod.PodLogResponse.logEntry:type_name -> apocryph.proto.v0.provisionPod.LogEntry - 0, // 5: apocryph.proto.v0.provisionPod.ProvisionPodService.ProvisionPod:input_type -> apocryph.proto.v0.provisionPod.ProvisionPodRequest - 3, // 6: apocryph.proto.v0.provisionPod.ProvisionPodService.UpdatePod:input_type -> apocryph.proto.v0.provisionPod.UpdatePodRequest - 1, // 7: apocryph.proto.v0.provisionPod.ProvisionPodService.DeletePod:input_type -> apocryph.proto.v0.provisionPod.DeletePodRequest - 7, // 8: apocryph.proto.v0.provisionPod.ProvisionPodService.GetPodLogs:input_type -> apocryph.proto.v0.provisionPod.PodLogRequest - 6, // 9: apocryph.proto.v0.provisionPod.ProvisionPodService.ProvisionPod:output_type -> apocryph.proto.v0.provisionPod.ProvisionPodResponse - 6, // 10: apocryph.proto.v0.provisionPod.ProvisionPodService.UpdatePod:output_type -> apocryph.proto.v0.provisionPod.ProvisionPodResponse - 2, // 11: apocryph.proto.v0.provisionPod.ProvisionPodService.DeletePod:output_type -> apocryph.proto.v0.provisionPod.DeletePodResponse - 8, // 12: apocryph.proto.v0.provisionPod.ProvisionPodService.GetPodLogs:output_type -> apocryph.proto.v0.provisionPod.PodLogResponse - 9, // [9:13] is the sub-list for method output_type - 5, // [5:9] is the sub-list for method input_type - 5, // [5:5] is the sub-list for extension type_name - 5, // [5:5] is the sub-list for extension extendee - 0, // [0:5] is the sub-list for field type_name + 5, // 3: apocryph.proto.v0.provisionPod.UpdatePodRequest.payment:type_name -> apocryph.proto.v0.provisionPod.PaymentChannel + 10, // 4: apocryph.proto.v0.provisionPod.ProvisionPodResponse.addresses:type_name -> apocryph.proto.v0.provisionPod.ProvisionPodResponse.ExposedHostPort + 9, // 5: apocryph.proto.v0.provisionPod.PodLogResponse.logEntry:type_name -> apocryph.proto.v0.provisionPod.LogEntry + 0, // 6: apocryph.proto.v0.provisionPod.ProvisionPodService.ProvisionPod:input_type -> apocryph.proto.v0.provisionPod.ProvisionPodRequest + 3, // 7: apocryph.proto.v0.provisionPod.ProvisionPodService.UpdatePod:input_type -> apocryph.proto.v0.provisionPod.UpdatePodRequest + 1, // 8: apocryph.proto.v0.provisionPod.ProvisionPodService.DeletePod:input_type -> apocryph.proto.v0.provisionPod.DeletePodRequest + 7, // 9: apocryph.proto.v0.provisionPod.ProvisionPodService.GetPodLogs:input_type -> apocryph.proto.v0.provisionPod.PodLogRequest + 6, // 10: apocryph.proto.v0.provisionPod.ProvisionPodService.ProvisionPod:output_type -> apocryph.proto.v0.provisionPod.ProvisionPodResponse + 6, // 11: apocryph.proto.v0.provisionPod.ProvisionPodService.UpdatePod:output_type -> apocryph.proto.v0.provisionPod.ProvisionPodResponse + 2, // 12: apocryph.proto.v0.provisionPod.ProvisionPodService.DeletePod:output_type -> apocryph.proto.v0.provisionPod.DeletePodResponse + 8, // 13: apocryph.proto.v0.provisionPod.ProvisionPodService.GetPodLogs:output_type -> apocryph.proto.v0.provisionPod.PodLogResponse + 10, // [10:14] is the sub-list for method output_type + 6, // [6:10] is the sub-list for method input_type + 6, // [6:6] is the sub-list for extension type_name + 6, // [6:6] is the sub-list for extension extendee + 0, // [0:6] is the sub-list for field type_name } func init() { file_provision_pod_proto_init() } diff --git a/pkg/provider/server.go b/pkg/provider/server.go index 2bbdda77..a596fc23 100644 --- a/pkg/provider/server.go +++ b/pkg/provider/server.go @@ -78,7 +78,7 @@ func (s *provisionPodServer) UpdatePod(ctx context.Context, request *connect.Req namespace := pbcon.GetNamespace(request) response := &pb.ProvisionPodResponse{} - err = tpk8s.ApplyPodRequest(ctx, s.k8cl, namespace, true, request.Msg.Pod, images, secrets, response) + err = tpk8s.ApplyPodRequest(ctx, s.k8cl, namespace, true, request.Msg.Pod, request.Msg.Payment, images, secrets, response) if err != nil { return transformError(err) } @@ -135,11 +135,12 @@ func (s *provisionPodServer) ProvisionPod(ctx context.Context, request *connect. if err != nil { return transformError(err) } + fmt.Printf("Authorized:%v\n", request.Msg.Pod.Authorized) response := &pb.ProvisionPodResponse{} ns := tpk8s.NewTrustedPodsNamespace(namespace, request.Msg.Payment) err = tpk8s.RunInNamespaceOrRevert(ctx, s.k8cl, ns, s.dryRun, func(cl client.Client) error { - return tpk8s.ApplyPodRequest(ctx, cl, ns.ObjectMeta.Name, false, request.Msg.Pod, images, secrets, response) + return tpk8s.ApplyPodRequest(ctx, cl, ns.ObjectMeta.Name, false, request.Msg.Pod, request.Msg.Payment, images, secrets, response) }) if err != nil { return transformError(err) diff --git a/pkg/publisher/connect.go b/pkg/publisher/connect.go index 78ecdf62..fec9ffc8 100644 --- a/pkg/publisher/connect.go +++ b/pkg/publisher/connect.go @@ -13,9 +13,13 @@ import ( "strings" "connectrpc.com/connect" + "github.com/comrade-coop/apocryph/pkg/abi" "github.com/comrade-coop/apocryph/pkg/ipfs" pb "github.com/comrade-coop/apocryph/pkg/proto" pbcon "github.com/comrade-coop/apocryph/pkg/proto/protoconnect" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" "github.com/libp2p/go-libp2p/core/peer" tpipfs "github.com/comrade-coop/apocryph/pkg/ipfs" @@ -57,7 +61,7 @@ func ConnectToProvider(ipfsP2p *ipfs.P2pApi, deployment *pb.Deployment, intercep }, nil } -func SendToProvider(ctx context.Context, ipfsP2p *ipfs.P2pApi, pod *pb.Pod, deployment *pb.Deployment, client *P2pProvisionPodServiceClient) error { +func SendToProvider(ctx context.Context, ipfsP2p *ipfs.P2pApi, pod *pb.Pod, deployment *pb.Deployment, client *P2pProvisionPodServiceClient, ethClient *ethclient.Client, publisherAuth *bind.TransactOpts) error { // tpipfs.NewP2pApi(ipfs, ipfsMultiaddr) pod = LinkUploadsFromDeployment(pod, deployment) defer client.Close() @@ -97,8 +101,22 @@ func SendToProvider(ctx context.Context, ipfsP2p *ipfs.P2pApi, pod *pb.Pod, depl return fmt.Errorf("Error from provider: %w", errors.New(response.Msg.Error)) } + if response.Msg.PubAddress != "" { + // authorize the public address to control the payment channel + // get a payment contract instance + payment, err := abi.NewPayment(common.Address(deployment.Payment.PaymentContractAddress), ethClient) + if err != nil { + return fmt.Errorf("Failed instantiating payment contract: %w", err) + } + tx, err := payment.Authorize(publisherAuth, common.HexToAddress(response.Msg.PubAddress), common.Address(deployment.Provider.EthereumAddress), [32]byte(deployment.Payment.PodID)) + if err != nil { + return fmt.Errorf("Failed Authorizing Address: %w", err) + } + fmt.Fprintf(os.Stdout, "Authorized Address Successfully %v\n", tx) + } + deployment.Deployed = response.Msg - fmt.Fprintf(os.Stderr, "Successfully deployed! %v\n", response) + fmt.Fprintf(os.Stdout, "Successfully deployed! %v\n", response) } else { request := &pb.DeletePodRequest{} response, err := client.DeletePod(ctx, connect.NewRequest(request)) diff --git a/proto/pod.proto b/proto/pod.proto index 05bff8b9..c2423241 100644 --- a/proto/pod.proto +++ b/proto/pod.proto @@ -9,6 +9,7 @@ message Pod { repeated Container containers = 1; repeated Volume volumes = 2; Replicas replicas = 3; + bool authorized = 4; } message Container { diff --git a/proto/provision-pod.proto b/proto/provision-pod.proto index 7139388b..98abf6ff 100644 --- a/proto/provision-pod.proto +++ b/proto/provision-pod.proto @@ -28,6 +28,7 @@ message DeletePodResponse { message UpdatePodRequest { pod.Pod pod = 1; + PaymentChannel payment = 2; } message UpdatePodResponse { bool success = 1; @@ -51,6 +52,7 @@ message ProvisionPodResponse { string containerName = 2; uint64 containerPort = 3; } + string pubAddress = 4; } message PodLogRequest{ diff --git a/test/e2e/autoscaler/run-test.sh b/test/e2e/autoscaler/run-test.sh index 5067acb2..0333d0fd 100755 --- a/test/e2e/autoscaler/run-test.sh +++ b/test/e2e/autoscaler/run-test.sh @@ -114,6 +114,7 @@ go run ../../../cmd/trustedpods registry get --config ../../integration/registry --token-contract 0x5FbDB2315678afecb367f032d93F642f64180aa3 \ --ipfs /ip4/127.0.0.1/tcp/5004 \ +sleep 5 ## 5.0: Deploy the autoscaler to the providers using their p2p multiaddr set -v @@ -138,8 +139,8 @@ go run ../../../cmd/trustedpods/ pod deploy ../common/manifest-autoscaler.yaml \ --upload-images=true \ --mint-funds \ --provider /p2p/"$PROVIDER_IPFS" \ - --provider-eth "$PROVIDER_ETH" - + --provider-eth "$PROVIDER_ETH" \ + --authorize sleep 5 ## 5.2: deploy to the second cluster @@ -164,7 +165,8 @@ go run ../../../cmd/trustedpods/ pod deploy ../common/manifest-autoscaler.yaml \ --upload-images=true \ --mint-funds \ --provider /p2p/"$PROVIDER_IPFS" \ - --provider-eth "$PROVIDER_ETH" + --provider-eth "$PROVIDER_ETH" \ + --authorize sleep 5 @@ -191,7 +193,8 @@ go run ../../../cmd/trustedpods/ pod deploy ../common/manifest-autoscaler.yaml \ --upload-images=true \ --mint-funds \ --provider /p2p/"$PROVIDER_IPFS" \ - --provider-eth "$PROVIDER_ETH" + --provider-eth "$PROVIDER_ETH" \ + --authorize ## 6.0: Connect the cluster From c4fa730576745edc050ba82770915d3e3d3f3510 Mon Sep 17 00:00:00 2001 From: revoltez Date: Tue, 30 Jul 2024 21:02:22 +0100 Subject: [PATCH 2/8] feat!: allow authorized apps to create sub payment channels --- autoscaler/main.go | 6 +- cmd/trustedpods/deploy.go | 19 +++-- cmd/trustedpods/sync.go | 4 +- pkg/autoscaler/server.go | 43 ++++++----- pkg/ethereum/client.go | 31 ++++---- pkg/kubernetes/pods.go | 11 ++- pkg/publisher/connect.go | 38 +++------- pkg/publisher/deployment.go | 92 ++++++++++++++++++++++++ test/e2e/common/manifest-autoscaler.yaml | 2 +- 9 files changed, 168 insertions(+), 78 deletions(-) diff --git a/autoscaler/main.go b/autoscaler/main.go index 58a0aecc..63e88378 100644 --- a/autoscaler/main.go +++ b/autoscaler/main.go @@ -14,15 +14,15 @@ import ( func main() { mux := http.NewServeMux() - self, err := tpraft.NewPeer(fmt.Sprintf("/ip4/0.0.0.0/tcp/%v", autoscaler.RAFT_P2P_PORT)) + p2pHost, err := tpraft.NewPeer(fmt.Sprintf("/ip4/0.0.0.0/tcp/%v", autoscaler.RAFT_P2P_PORT)) if err != nil { fmt.Println("Failed creating p2p node") return } - fmt.Printf("PEER ID: %v\n", self.ID()) + log.Printf("PEER ID: %v\n", p2pHost.ID()) - server, err := autoscaler.NewAutoSalerServer("http://eth-rpc.eth.svc.cluster.local:8545") + server, err := autoscaler.NewAutoSalerServer("http://eth-rpc.eth.svc.cluster.local:8545", p2pHost) if err != nil { fmt.Println("Failed creating AutoScaler Server") return diff --git a/cmd/trustedpods/deploy.go b/cmd/trustedpods/deploy.go index 7c09454b..8b3778b3 100644 --- a/cmd/trustedpods/deploy.go +++ b/cmd/trustedpods/deploy.go @@ -11,6 +11,7 @@ import ( "github.com/comrade-coop/apocryph/pkg/ethereum" "github.com/comrade-coop/apocryph/pkg/ipcr" tpipfs "github.com/comrade-coop/apocryph/pkg/ipfs" + pb "github.com/comrade-coop/apocryph/pkg/proto" pbcon "github.com/comrade-coop/apocryph/pkg/proto/protoconnect" "github.com/comrade-coop/apocryph/pkg/publisher" "github.com/ethereum/go-ethereum/accounts/abi/bind" @@ -94,7 +95,6 @@ var deployPodCmd = &cobra.Command{ configureDeployment(deployment) if authorize { - fmt.Println("Authorizing ...") pod.Authorized = true } @@ -184,10 +184,20 @@ var deployPodCmd = &cobra.Command{ return err } - err = publisher.SendToProvider(cmd.Context(), ipfsp2p, pod, deployment, provisionPodclient, ethClient, publisherAuth) + fmt.Printf("PODID is:%v\n", common.BytesToHash(deployment.Payment.PodID)) + + response, err := publisher.SendToProvider(cmd.Context(), ipfsp2p, pod, deployment, provisionPodclient) if err != nil { return err } + // Authorize the application to manipulate the payment channel and fund + // it to make it able to send transactions + if authorize { + err := publisher.AuthorizeAndFundApplication(cmd.Context(), response.(*pb.ProvisionPodResponse), deployment, ethClient, publisherAuth, publisherKey, 1000000000000000000) + if err != nil { + return err + } + } return publisher.SaveDeployment(deploymentFile, deploymentFormat, deployment) }, @@ -220,7 +230,7 @@ var deletePodCmd = &cobra.Command{ publisherKey = common.BytesToAddress(deployment.Payment.PublisherAddress).String() } - publisherAuth, sign, err := ethereum.GetAccountAndSigner(publisherKey, ethClient) + _, sign, err := ethereum.GetAccountAndSigner(publisherKey, ethClient) if err != nil { return fmt.Errorf("Could not get ethereum account: %w", err) } @@ -234,10 +244,11 @@ var deletePodCmd = &cobra.Command{ return err } - err = publisher.SendToProvider(cmd.Context(), tpipfs.NewP2pApi(ipfs, ipfsMultiaddr), nil, deployment, client, ethClient, publisherAuth) + _, err = publisher.SendToProvider(cmd.Context(), tpipfs.NewP2pApi(ipfs, ipfsMultiaddr), nil, deployment, client) if err != nil { return err } + return publisher.SaveDeployment(deploymentFile, deploymentFormat, deployment) }, } diff --git a/cmd/trustedpods/sync.go b/cmd/trustedpods/sync.go index 0acf21f0..126521ea 100644 --- a/cmd/trustedpods/sync.go +++ b/cmd/trustedpods/sync.go @@ -40,7 +40,7 @@ var syncPodCmd = &cobra.Command{ publisherKey = common.BytesToAddress(deployment.Payment.PublisherAddress).String() } - publisherAuth, sign, err := ethereum.GetAccountAndSigner(publisherKey, ethClient) + _, sign, err := ethereum.GetAccountAndSigner(publisherKey, ethClient) if err != nil { return fmt.Errorf("Could not get ethereum account: %w", err) } @@ -54,7 +54,7 @@ var syncPodCmd = &cobra.Command{ return err } - err = publisher.SendToProvider(cmd.Context(), tpipfs.NewP2pApi(ipfs, ipfsMultiaddr), pod, deployment, client, ethClient, publisherAuth) + _, err = publisher.SendToProvider(cmd.Context(), tpipfs.NewP2pApi(ipfs, ipfsMultiaddr), pod, deployment, client) if err != nil { return err } diff --git a/pkg/autoscaler/server.go b/pkg/autoscaler/server.go index 2b3e1720..4e71a926 100644 --- a/pkg/autoscaler/server.go +++ b/pkg/autoscaler/server.go @@ -36,7 +36,7 @@ type AutoScalerServer struct { store *tpraft.KVStore peers []string started bool - self host.Host + p2pHost host.Host nodeGateway string ChannelManager *PaymentChannelManager MainLoop func(*AutoScalerServer) @@ -51,16 +51,7 @@ type PaymentChannelManager struct { Payment *abi.Payment } -func (s *AutoScalerServer) TriggerNode(c context.Context, req *connect.Request[pb.ConnectClusterRequest]) (*connect.Response[pb.TriggerNodeResponse], error) { - if s.started == false { - log.Println("Node Triggered") - go s.BoostrapCluster(req) - s.started = true - } - return connect.NewResponse(&pb.TriggerNodeResponse{PeerID: s.self.ID().String()}), nil -} - -func NewAutoSalerServer(ethereumRpc string) (*AutoScalerServer, error) { +func NewAutoSalerServer(ethereumRpc string, p2pHost host.Host) (*AutoScalerServer, error) { ethClient, err := ethereum.GetClient(ethereumRpc) if err != nil { @@ -71,7 +62,7 @@ func NewAutoSalerServer(ethereumRpc string) (*AutoScalerServer, error) { paymentAddress := common.HexToAddress(os.Getenv(constants.PAYMENT_ADDR_KEY)) publisherAddress := common.HexToAddress(os.Getenv(constants.PUBLISHER_ADDR_KEY)) providerAddress := common.HexToAddress(os.Getenv(constants.PROVIDER_ADDR_KEY)) - podId := common.BytesToHash([]byte(os.Getenv(constants.POD_ID_KEY))) + podId := common.HexToHash((os.Getenv(constants.POD_ID_KEY))) log.Printf("ENV Variables: Payment_Address: %v, Publisher Address: %v, ProviderAddress: %v, podId: %v\n", paymentAddress, publisherAddress, providerAddress, podId) @@ -93,6 +84,7 @@ func NewAutoSalerServer(ethereumRpc string) (*AutoScalerServer, error) { } return &AutoScalerServer{ + p2pHost: p2pHost, ChannelManager: &PaymentChannelManager{ Publisher: publisherAddress, Provider: providerAddress, @@ -104,6 +96,15 @@ func NewAutoSalerServer(ethereumRpc string) (*AutoScalerServer, error) { }, nil } +func (s *AutoScalerServer) TriggerNode(c context.Context, req *connect.Request[pb.ConnectClusterRequest]) (*connect.Response[pb.TriggerNodeResponse], error) { + if s.started == false { + log.Println("Node Triggered") + go s.BoostrapCluster(req) + s.started = true + } + return connect.NewResponse(&pb.TriggerNodeResponse{PeerID: s.p2pHost.ID().String()}), nil +} + func (s *AutoScalerServer) BoostrapCluster(req *connect.Request[pb.ConnectClusterRequest]) error { peerIDs, err := s.FetchPeerIDsFromServers(req) @@ -132,7 +133,7 @@ func (s *AutoScalerServer) BoostrapCluster(req *connect.Request[pb.ConnectCluste log.Printf("Added Peer %v ID:%s \n", peerInfo.Addrs, peerInfo.ID.String()) } - node, err := tpraft.NewRaftNode(s.self, peers, RAFT_PATH) + node, err := tpraft.NewRaftNode(s.p2pHost, peers, RAFT_PATH) if err != nil { log.Println("Error:Could not Creat Raft Node") return fmt.Errorf("Failed Creating Raft Node %v\n", err) @@ -175,13 +176,16 @@ func (s *AutoScalerServer) FetchPeerIDsFromServers(req *connect.Request[pb.Conne http.DefaultClient, addr) + req.Header().Set("Host", "autoscaler.local") + resp, err := client.TriggerNode(context.Background(), req) if err != nil { - return nil, fmt.Errorf("failed to get PeerID from server %v: %w", addr, err) + log.Printf("failed to connect to PeerID from server %v: %v", addr, err) + continue } peerIDs[addr] = resp.Msg.PeerID } - + log.Printf("PeerIDs collected: %v", peerIDs) return peerIDs, nil } @@ -210,14 +214,14 @@ func (s *AutoScalerServer) waitLeaderElection(timeout uint32) error { switch obs.Data.(type) { case raft.RaftState: if leaderAddr, _ := s.node.Raft.LeaderWithID(); leaderAddr != "" { - fmt.Printf("Leader Elected: %v\n", leaderAddr) + log.Printf("Leader Elected: %v\n", leaderAddr) go s.MainLoop(s) return nil } } case <-ticker.C: if leaderAddr, _ := s.node.Raft.LeaderWithID(); leaderAddr != "" { - fmt.Printf("Leader Elected: %v\n", leaderAddr) + log.Printf("Leader Elected: %v\n", leaderAddr) go s.MainLoop(s) return nil } @@ -241,11 +245,12 @@ func (s *AutoScalerServer) watchNewStates() { // example of main loop creating a subchannel, then setting the value of a test domain // with the current node gateway every 10 seconds func SetAppGatewayExample(s *AutoScalerServer) { - tx, err := s.ChannelManager.Payment.CreateSubChannel(s.ChannelManager.Transactor, s.ChannelManager.Publisher, s.ChannelManager.Provider, s.ChannelManager.PodId, s.ChannelManager.Provider, s.ChannelManager.PodId, big.NewInt(500)) + _, err := s.ChannelManager.Payment.CreateSubChannel(s.ChannelManager.Transactor, s.ChannelManager.Publisher, s.ChannelManager.Provider, s.ChannelManager.PodId, s.ChannelManager.Provider, s.ChannelManager.PodId, big.NewInt(200)) if err != nil { log.Printf("Failed to create subchannel: %v\n", err) + } else { + log.Printf("SubChannel Created Succefully \n") } - log.Printf("Sub Channel Created Succefully, TX HASH: %v\n", tx.Hash()) log.Println("Starting Main Loop:") for { if s.node.Raft.State() == raft.Leader { diff --git a/pkg/ethereum/client.go b/pkg/ethereum/client.go index 5be485fd..e63e19ce 100644 --- a/pkg/ethereum/client.go +++ b/pkg/ethereum/client.go @@ -5,8 +5,7 @@ package ethereum import ( "context" "crypto/ecdsa" - "crypto/x509" - "encoding/pem" + "encoding/hex" "fmt" "strings" @@ -127,23 +126,23 @@ func GetAccountAndSigner(accountString string, client *ethclient.Client) (*bind. } } -// Encode private key func EncodePrivateKey(privateKey *ecdsa.PrivateKey) (string, error) { - x509Encoded, err := x509.MarshalECPrivateKey(privateKey) + privateKeyBytes := crypto.FromECDSA(privateKey) + return hex.EncodeToString(privateKeyBytes), nil +} + +func DecodePrivateKey(encodedKey string) (*ecdsa.PrivateKey, error) { + // Decode the hex string + privateKeyBytes, err := hex.DecodeString(encodedKey) if err != nil { - return "", err + return nil, fmt.Errorf("failed to decode hex string: %w", err) } - pemEncoded := pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: x509Encoded}) - return string(pemEncoded), nil -} -// Decode private key -func DecodePrivateKey(pemEncoded string) (*ecdsa.PrivateKey, error) { - block, _ := pem.Decode([]byte(pemEncoded)) - if block == nil { - return nil, fmt.Errorf("Could decode Pem Encoded key") + // Convert bytes to ECDSA private key + privateKey, err := crypto.ToECDSA(privateKeyBytes) + if err != nil { + return nil, fmt.Errorf("failed to convert bytes to ECDSA private key: %w", err) } - x509Encoded := block.Bytes - privateKey, err := x509.ParseECPrivateKey(x509Encoded) - return privateKey, err + + return privateKey, nil } diff --git a/pkg/kubernetes/pods.go b/pkg/kubernetes/pods.go index d3a970da..449441ad 100644 --- a/pkg/kubernetes/pods.go +++ b/pkg/kubernetes/pods.go @@ -14,7 +14,6 @@ import ( pb "github.com/comrade-coop/apocryph/pkg/proto" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/crypto/secp256k1" kedahttpv1alpha1 "github.com/kedacore/http-add-on/operator/apis/http/v1alpha1" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -106,11 +105,10 @@ func ApplyPodRequest( if podManifest.Authorized == true { // create the keypair that will be accessible for all pods var err error - privateKey, err = ecdsa.GenerateKey(secp256k1.S256(), rand.Reader) + privateKey, err = ecdsa.GenerateKey(crypto.S256(), rand.Reader) if err != nil { - return fmt.Errorf("Could not create private key for the application") + return fmt.Errorf("Could not create private key for the application: %w", err) } - // Ensure the public key is valid before getting the address if privateKey == nil || privateKey.PublicKey.X == nil || privateKey.PublicKey.Y == nil { return fmt.Errorf("Generated an invalid public key") @@ -139,14 +137,15 @@ func ApplyPodRequest( key, err := ethereum.EncodePrivateKey(privateKey) if err != nil { - return err + return fmt.Errorf("Failed encoding private key: %v\n", err) } + fmt.Println("Setting Env variables:") containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: constants.PRIVATE_KEY, Value: key}) // save as hex to parse later as hex containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: constants.PAYMENT_ADDR_KEY, Value: common.BytesToAddress(paymentChannel.ContractAddress).Hex()}) containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: constants.PUBLISHER_ADDR_KEY, Value: common.BytesToAddress(paymentChannel.PublisherAddress).Hex()}) containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: constants.PROVIDER_ADDR_KEY, Value: common.BytesToAddress(paymentChannel.ProviderAddress).Hex()}) - containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: constants.POD_ID_KEY, Value: string(paymentChannel.PodID)}) + containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: constants.POD_ID_KEY, Value: common.BytesToHash(paymentChannel.PodID).Hex()}) containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: constants.PRIVATE_KEY, Value: key}) containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: constants.PUBLIC_ADDRESS_KEY, Value: address.Hex()}) diff --git a/pkg/publisher/connect.go b/pkg/publisher/connect.go index fec9ffc8..4dac0237 100644 --- a/pkg/publisher/connect.go +++ b/pkg/publisher/connect.go @@ -13,13 +13,9 @@ import ( "strings" "connectrpc.com/connect" - "github.com/comrade-coop/apocryph/pkg/abi" "github.com/comrade-coop/apocryph/pkg/ipfs" pb "github.com/comrade-coop/apocryph/pkg/proto" pbcon "github.com/comrade-coop/apocryph/pkg/proto/protoconnect" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethclient" "github.com/libp2p/go-libp2p/core/peer" tpipfs "github.com/comrade-coop/apocryph/pkg/ipfs" @@ -61,7 +57,7 @@ func ConnectToProvider(ipfsP2p *ipfs.P2pApi, deployment *pb.Deployment, intercep }, nil } -func SendToProvider(ctx context.Context, ipfsP2p *ipfs.P2pApi, pod *pb.Pod, deployment *pb.Deployment, client *P2pProvisionPodServiceClient, ethClient *ethclient.Client, publisherAuth *bind.TransactOpts) error { +func SendToProvider(ctx context.Context, ipfsP2p *ipfs.P2pApi, pod *pb.Pod, deployment *pb.Deployment, client *P2pProvisionPodServiceClient) (interface{}, error) { // tpipfs.NewP2pApi(ipfs, ipfsMultiaddr) pod = LinkUploadsFromDeployment(pod, deployment) defer client.Close() @@ -84,7 +80,7 @@ func SendToProvider(ctx context.Context, ipfsP2p *ipfs.P2pApi, pod *pb.Pod, depl fmt.Println("Processing Request ...") response, err = client.ProvisionPod(ctx, connect.NewRequest(request)) if err != nil { - return fmt.Errorf("Failed executing provision pod request: %w", err) + return nil, fmt.Errorf("Failed executing provision pod request: %w", err) } } else { request := &pb.UpdatePodRequest{ @@ -93,42 +89,30 @@ func SendToProvider(ctx context.Context, ipfsP2p *ipfs.P2pApi, pod *pb.Pod, depl response, err = client.UpdatePod(ctx, connect.NewRequest(request)) if err != nil { - return fmt.Errorf("Failed executing update pod request: %w", err) + return nil, fmt.Errorf("Failed executing update pod request: %w", err) } + return response.Msg, nil } if response.Msg.Error != "" { - return fmt.Errorf("Error from provider: %w", errors.New(response.Msg.Error)) + return nil, fmt.Errorf("Error from provider: %w", errors.New(response.Msg.Error)) } - - if response.Msg.PubAddress != "" { - // authorize the public address to control the payment channel - // get a payment contract instance - payment, err := abi.NewPayment(common.Address(deployment.Payment.PaymentContractAddress), ethClient) - if err != nil { - return fmt.Errorf("Failed instantiating payment contract: %w", err) - } - tx, err := payment.Authorize(publisherAuth, common.HexToAddress(response.Msg.PubAddress), common.Address(deployment.Provider.EthereumAddress), [32]byte(deployment.Payment.PodID)) - if err != nil { - return fmt.Errorf("Failed Authorizing Address: %w", err) - } - fmt.Fprintf(os.Stdout, "Authorized Address Successfully %v\n", tx) - } - deployment.Deployed = response.Msg fmt.Fprintf(os.Stdout, "Successfully deployed! %v\n", response) + + return response.Msg, nil + } else { request := &pb.DeletePodRequest{} response, err := client.DeletePod(ctx, connect.NewRequest(request)) if err != nil { - return fmt.Errorf("Failed executing update pod request: %w", err) + return nil, fmt.Errorf("Failed executing update pod request: %w", err) } if response.Msg.Error != "" { - return fmt.Errorf("Error from provider: %w", errors.New(response.Msg.Error)) + return nil, fmt.Errorf("Error from provider: %w", errors.New(response.Msg.Error)) } deployment.Deployed = nil fmt.Fprintf(os.Stderr, "Successfully undeployed!\n") + return response.Msg, nil } - - return nil } diff --git a/pkg/publisher/deployment.go b/pkg/publisher/deployment.go index 55248498..19695c92 100644 --- a/pkg/publisher/deployment.go +++ b/pkg/publisher/deployment.go @@ -3,21 +3,34 @@ package publisher import ( + "context" + "crypto/ecdsa" "crypto/sha256" "encoding/hex" "errors" "fmt" "io/fs" + "math/big" "os" "path/filepath" + "strings" + "github.com/comrade-coop/apocryph/pkg/abi" pb "github.com/comrade-coop/apocryph/pkg/proto" + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethclient" "github.com/mitchellh/go-homedir" ) var DefaultDeploymentPath = "~/.apocryph/deployment" var DefaultPodFile = "manifest.yaml" +const PrivateKeySize = 256 / 8 + func GenerateDeploymentFilename(podFile string, deploymentFormat string) (deploymentFile string, relPodFile string, err error) { if deploymentFormat == "" { deploymentFormat = "yaml" @@ -110,3 +123,82 @@ func SaveDeployment(deploymentFile string, deploymentFormat string, deployment * // } return nil } + +func AuthorizeAndFundApplication(ctx context.Context, response *pb.ProvisionPodResponse, deployment *pb.Deployment, ethClient *ethclient.Client, publisherAuth *bind.TransactOpts, publisherKey string, amount int64) error { + if response.PubAddress != "" { + // authorize the public address to control the payment channel + // get a payment contract instance + payment, err := abi.NewPayment(common.Address(deployment.Payment.PaymentContractAddress), ethClient) + if err != nil { + return fmt.Errorf("Failed instantiating payment contract: %w", err) + } + _, err = payment.Authorize(publisherAuth, common.HexToAddress(response.PubAddress), common.Address(deployment.Provider.EthereumAddress), [32]byte(deployment.Payment.PodID)) + if err != nil { + return fmt.Errorf("Failed Authorizing Address: %w", err) + } + + fmt.Fprintf(os.Stdout, "Authorized Address Successfully %v\n", response.PubAddress) + + // NOTE: the deployed application must be funded with the base + // currency (eth) in order for it to be able to make transactions + // (like creating subchannels) + pubAddress := common.HexToAddress(response.PubAddress) + amount := big.NewInt(amount) + + // Estimate gas limit + gasLimit, err := ethClient.EstimateGas(context.Background(), ethereum.CallMsg{ + From: publisherAuth.From, + To: &pubAddress, + Value: amount, + }) + if err != nil { + return fmt.Errorf("Failed to estimate gas: %w", err) + } + + // Get gas price + gasPrice, err := ethClient.SuggestGasPrice(context.Background()) + if err != nil { + return fmt.Errorf("Failed to get gas price: %w", err) + } + + nonce, err := ethClient.PendingNonceAt(ctx, publisherAuth.From) + if err != nil { + return fmt.Errorf("Failed to get gas price: %w", err) + } + + // Create a transaction + tx := types.NewTransaction( + nonce, + pubAddress, + amount, + gasLimit, + gasPrice, + nil, + ) + chainId, err := ethClient.ChainID(ctx) + if err != nil { + return fmt.Errorf("Failed to get chain ID: %w", err) + } + + var privateKey *ecdsa.PrivateKey + if privKey, ok := strings.CutPrefix(publisherKey, "0x"); ok && len(privKey) == PrivateKeySize*2 { + privateKey, err = crypto.HexToECDSA(privKey) + if err != nil { + return err + } + } + + // Sign the transaction + signedTx, err := types.SignTx(tx, types.NewEIP155Signer(chainId), privateKey) + if err != nil { + return fmt.Errorf("Failed to sign transaction: %w", err) + } + + // Send the transaction + err = ethClient.SendTransaction(context.Background(), signedTx) + if err != nil { + return fmt.Errorf("Failed to send transaction: %w", err) + } + } + return nil +} diff --git a/test/e2e/common/manifest-autoscaler.yaml b/test/e2e/common/manifest-autoscaler.yaml index 1bd6aeb7..4c5fd738 100644 --- a/test/e2e/common/manifest-autoscaler.yaml +++ b/test/e2e/common/manifest-autoscaler.yaml @@ -4,7 +4,7 @@ containers: url: localhost:5000/comradecoop/apocryph/autoscaler ports: - containerPort: '8080' - hostHttpHost: autoscaler.local + hostHttpHost: 'autoscaler.local' name: internal - containerPort: '32500' hostTcpPort: 32500 From 1b1280002f31db29de77329eba89c4931dbe70e4 Mon Sep 17 00:00:00 2001 From: revoltez Date: Thu, 1 Aug 2024 19:11:32 +0100 Subject: [PATCH 3/8] feat: allow publisher to manage subchannels --- contracts/src/Payment.sol | 32 +++++++++----- contracts/test/Payment.t.sol | 85 ++++++++++++++++++++++++++++-------- pkg/abi-ts/generated.ts | 3 ++ pkg/abi/Payment.abi.go | 74 +++++++++++++++---------------- 4 files changed, 129 insertions(+), 65 deletions(-) diff --git a/contracts/src/Payment.sol b/contracts/src/Payment.sol index 79b94e21..2442cb48 100644 --- a/contracts/src/Payment.sol +++ b/contracts/src/Payment.sol @@ -75,11 +75,13 @@ contract Payment { } // initiate the process of unlocking the funds stored in the contract - function unlock(address provider, bytes32 podId) public { - address publisher = msg.sender; + function unlock(address publisher, address provider, bytes32 podId) public { + // check if the caller is authorized to unlock channel Channel storage channel = channels[publisher][provider][podId]; if (channel.investedByPublisher == 0) revert DoesNotExist(); - + if (msg.sender != publisher) { + if (channel.authorized[msg.sender] == false) revert NotAuthorized(); + } uint256 newUnlockedAt = block.timestamp + channel.unlockTime; if (channel.unlockedAt == 0 || channel.unlockedAt < newUnlockedAt) { channel.unlockedAt = newUnlockedAt; @@ -88,9 +90,12 @@ contract Payment { } // transfer the now-unlocked funds back to the publisher - function withdrawUnlocked(address provider, bytes32 podId) public { - address publisher = msg.sender; + function withdrawUnlocked(address publisher, address provider, bytes32 podId) public { + // check if the caller is authorized to withdraw Channel storage channel = channels[publisher][provider][podId]; + if (msg.sender != publisher) { + if (channel.authorized[msg.sender] == false) revert NotAuthorized(); + } if (channel.unlockedAt == 0 || block.timestamp < channel.unlockedAt) revert ChannelLocked(); uint256 leftoverFunds = channel.investedByPublisher - channel.withdrawnByProvider; @@ -100,13 +105,17 @@ contract Payment { emit Unlocked(publisher, provider, podId, leftoverFunds); - token.safeTransfer(publisher, leftoverFunds); + token.safeTransfer(msg.sender, leftoverFunds); } // withdrawUnlockedFunds and destroy all previous traces of the channel's existence - function closeChannel(address provider, bytes32 podId) public { - address publisher = msg.sender; + function closeChannel(address publisher, address provider, bytes32 podId) public { + // check if the caller is authorized to close the channel Channel storage channel = channels[publisher][provider][podId]; + if (channel.investedByPublisher == 0) revert DoesNotExist(); + if (msg.sender != publisher) { + if (channel.authorized[msg.sender] == false) revert NotAuthorized(); + } if (channel.unlockedAt == 0 || block.timestamp < channel.unlockedAt) revert ChannelLocked(); uint256 leftoverFunds = channel.investedByPublisher - channel.withdrawnByProvider; @@ -115,7 +124,7 @@ contract Payment { if (leftoverFunds != 0) emit Unlocked(publisher, provider, podId, leftoverFunds); emit ChannelClosed(publisher, provider, podId); - if (leftoverFunds != 0) token.safeTransfer(publisher, leftoverFunds); + if (leftoverFunds != 0) token.safeTransfer(msg.sender, leftoverFunds); } // allows the provider to withdraw as many tokens as would be needed to reach totalWithdrawAmount since the opening of the channel @@ -202,8 +211,11 @@ contract Payment { // Create the subChannel for the authorized caller Channel storage subChannel = channels[msg.sender][newProvider][newPodId]; + // authorize the main channel publisher to control the subchannel + subChannel.authorized[publisher] = true; + // fund the new sub channel with the deducted amount from the main channel - subChannel.investedByPublisher = amount; + subChannel.investedByPublisher += amount; subChannel.unlockTime = channel.unlockTime; // Inherit unlock time from main channel emit Deposited(msg.sender, newProvider, newPodId, amount); diff --git a/contracts/test/Payment.t.sol b/contracts/test/Payment.t.sol index 16d0a273..03226e6d 100644 --- a/contracts/test/Payment.t.sol +++ b/contracts/test/Payment.t.sol @@ -100,12 +100,12 @@ contract PaymentTest is Test { token.approve(address(payment), 1000); vm.expectRevert(Payment.DoesNotExist.selector); - payment.unlock(provider, podId); + payment.unlock(publisher, provider, podId); payment.createChannel(provider, podId, 20, 500); vm.expectRevert(Payment.ChannelLocked.selector); - payment.withdrawUnlocked(provider, podId); + payment.withdrawUnlocked(publisher, provider, podId); vm.startPrank(provider); payment.withdraw(publisher, podId, 100, address(0)); @@ -113,22 +113,22 @@ contract PaymentTest is Test { vm.startPrank(publisher); vm.expectRevert(Payment.ChannelLocked.selector); - payment.withdrawUnlocked(provider, podId); + payment.withdrawUnlocked(publisher, provider, podId); - payment.unlock(provider, podId); + payment.unlock(publisher, provider, podId); // advance the block timestamp vm.warp(block.timestamp + 20); - payment.withdrawUnlocked(provider, podId); + payment.withdrawUnlocked(publisher, provider, podId); assertEq(400, token.balanceOf(publisher)); vm.expectRevert(Payment.AmountRequired.selector); - payment.withdrawUnlocked(provider, podId); + payment.withdrawUnlocked(publisher, provider, podId); vm.expectRevert(Payment.AlreadyExists.selector); payment.createChannel(provider, podId, 20, 400); - payment.closeChannel(provider, podId); + payment.closeChannel(publisher, provider, podId); payment.createChannel(provider, podId, 20, 400); } @@ -140,11 +140,11 @@ contract PaymentTest is Test { payment.createChannel(provider, podId, 20, 500); - payment.unlock(provider, podId); + payment.unlock(publisher, provider, podId); vm.warp(10); vm.expectRevert(Payment.ChannelLocked.selector); - payment.withdrawUnlocked(provider, podId); + payment.withdrawUnlocked(publisher, provider, podId); vm.startPrank(provider); payment.withdrawUpTo(publisher, podId, 200, address(0)); @@ -152,7 +152,7 @@ contract PaymentTest is Test { vm.startPrank(publisher); - payment.withdrawUnlocked(provider, podId); + payment.withdrawUnlocked(publisher, provider, podId); assertEq(token.balanceOf(publisher), 300); } @@ -194,8 +194,7 @@ contract PaymentTest is Test { // Test creating a sub-channel vm.startPrank(authorizedAddr); address newProvider = address(0x456); - payment.createSubChannel(publisher, provider, podId, newProvider, - newPodId, 200); + payment.createSubChannel(publisher, provider, podId, newProvider, newPodId, 200); // Verify sub-channel creation (uint256 investedAmount, uint256 withdrawnAmount, uint256 unlockTime,) = @@ -210,22 +209,72 @@ contract PaymentTest is Test { // Test creating sub-channel with insufficient funds vm.expectRevert(Payment.InsufficientFunds.selector); - payment.createSubChannel(publisher, provider, podId, newProvider, - newPodId,400); + payment.createSubChannel(publisher, provider, podId, newProvider, newPodId, 400); // Test creating sub-channel from non-existent main channel bytes32 nonExistentPodId = keccak256("non-existent"); vm.expectRevert(Payment.DoesNotExist.selector); - payment.createSubChannel(publisher, provider, nonExistentPodId, - newProvider, newPodId,100); + payment.createSubChannel(publisher, provider, nonExistentPodId, newProvider, newPodId, 100); // Test creating sub-channel without authorization vm.stopPrank(); vm.startPrank(address(0x789)); // Non-authorized address vm.expectRevert(Payment.NotAuthorized.selector); - payment.createSubChannel(publisher, provider, podId, - newProvider,newPodId, 100); + payment.createSubChannel(publisher, provider, podId, newProvider, newPodId, 100); vm.stopPrank(); } + + function test_close_channel() public { + vm.startPrank(publisher); + token.mint(500); + token.approve(address(payment), 500); + bytes32 newPodId = bytes32(uint256(1)); + + payment.createChannel(provider, podId, 0, 500); + payment.unlock(publisher, provider, podId); + uint256 balanceBeforeClose = token.balanceOf(publisher); + payment.closeChannel(publisher, provider, podId); + uint256 balanceAfterClose = token.balanceOf(publisher); + assertEq(balanceAfterClose - balanceBeforeClose, 500, "Caller should receive 500 tokens back"); + + // test closing a subchannel + token.approve(address(payment), 500); + payment.createChannel(provider, podId, 10, 500); // re-create the channel + address subChannelCreator = address(0x123); + payment.authorize(subChannelCreator, provider, podId); + vm.stopPrank(); + + vm.startPrank(subChannelCreator); + address newProvider = address(0x456); + payment.createSubChannel(publisher, provider, podId, newProvider, newPodId, 200); // create the subchannel + vm.stopPrank(); + + // close it + vm.startPrank(publisher); + balanceBeforeClose = token.balanceOf(publisher); + + vm.expectRevert(Payment.ChannelLocked.selector); // test closing locked channel + payment.closeChannel(subChannelCreator, newProvider, newPodId); + // advance time + payment.unlock(subChannelCreator, newProvider, newPodId); + vm.warp(block.timestamp + 11); + payment.closeChannel(subChannelCreator, newProvider, newPodId); + balanceAfterClose = token.balanceOf(publisher); + assertEq( + balanceAfterClose - balanceBeforeClose, + 200, + "Caller(publisher) should receive 200 tokens back after closing subchannel" + ); + + // test closing nonexistent Channel + vm.expectRevert(Payment.DoesNotExist.selector); + payment.closeChannel(subChannelCreator, newProvider, newPodId); + + // Test that non-authorized address can't close channel + vm.stopPrank(); + vm.prank(address(0xdead)); + vm.expectRevert(Payment.NotAuthorized.selector); + payment.closeChannel(publisher, provider, podId); + } } diff --git a/pkg/abi-ts/generated.ts b/pkg/abi-ts/generated.ts index 1e25f26f..21f34fd2 100644 --- a/pkg/abi-ts/generated.ts +++ b/pkg/abi-ts/generated.ts @@ -220,6 +220,7 @@ export const paymentAbi = [ { type: 'function', inputs: [ + { name: 'publisher', internalType: 'address', type: 'address' }, { name: 'provider', internalType: 'address', type: 'address' }, { name: 'podId', internalType: 'bytes32', type: 'bytes32' } ], @@ -286,6 +287,7 @@ export const paymentAbi = [ { type: 'function', inputs: [ + { name: 'publisher', internalType: 'address', type: 'address' }, { name: 'provider', internalType: 'address', type: 'address' }, { name: 'podId', internalType: 'bytes32', type: 'bytes32' } ], @@ -308,6 +310,7 @@ export const paymentAbi = [ { type: 'function', inputs: [ + { name: 'publisher', internalType: 'address', type: 'address' }, { name: 'provider', internalType: 'address', type: 'address' }, { name: 'podId', internalType: 'bytes32', type: 'bytes32' } ], diff --git a/pkg/abi/Payment.abi.go b/pkg/abi/Payment.abi.go index c6fb17e2..50a36eee 100644 --- a/pkg/abi/Payment.abi.go +++ b/pkg/abi/Payment.abi.go @@ -31,7 +31,7 @@ var ( // PaymentMetaData contains all meta data concerning the Payment contract. var PaymentMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_token\",\"type\":\"address\",\"internalType\":\"contractIERC20\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"authorize\",\"inputs\":[{\"name\":\"_authorized\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"available\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"channels\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"investedByPublisher\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"withdrawnByProvider\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"unlockTime\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"unlockedAt\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"closeChannel\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"createChannel\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"unlockTime\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"initialAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"createSubChannel\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"newProvider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"newPodId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"deposit\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isAuthorized\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_address\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"token\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIERC20\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"unlock\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdraw\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"transferAddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawUnlocked\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawUpTo\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"totalWithdrawAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"transferAddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawn\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"ChannelClosed\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ChannelCreated\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Deposited\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"depositAmount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"UnlockTimerStarted\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"unlockedAt\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unlocked\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"unlockedAmount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Withdrawn\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"withdrawnAmount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AddressEmptyCode\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"AlreadyExists\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AmountRequired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ChannelLocked\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"DoesNotExist\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"FailedCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InsufficientBalance\",\"inputs\":[{\"name\":\"balance\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"needed\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"InsufficientFunds\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotAuthorized\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SafeERC20FailedOperation\",\"inputs\":[{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"address\"}]}]", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_token\",\"type\":\"address\",\"internalType\":\"contractIERC20\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"authorize\",\"inputs\":[{\"name\":\"_authorized\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"available\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"channels\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"investedByPublisher\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"withdrawnByProvider\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"unlockTime\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"unlockedAt\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"closeChannel\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"createChannel\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"unlockTime\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"initialAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"createSubChannel\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"newProvider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"newPodId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"deposit\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isAuthorized\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_address\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"token\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIERC20\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"unlock\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdraw\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"transferAddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawUnlocked\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawUpTo\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"totalWithdrawAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"transferAddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawn\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"ChannelClosed\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ChannelCreated\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Deposited\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"depositAmount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"UnlockTimerStarted\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"unlockedAt\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unlocked\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"unlockedAmount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Withdrawn\",\"inputs\":[{\"name\":\"publisher\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"podId\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"withdrawnAmount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AddressEmptyCode\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"AlreadyExists\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AmountRequired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ChannelLocked\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"DoesNotExist\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"FailedCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InsufficientBalance\",\"inputs\":[{\"name\":\"balance\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"needed\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"InsufficientFunds\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotAuthorized\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SafeERC20FailedOperation\",\"inputs\":[{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"address\"}]}]", } // PaymentABI is the input ABI used to generate the binding from. @@ -380,25 +380,25 @@ func (_Payment *PaymentTransactorSession) Authorize(_authorized common.Address, return _Payment.Contract.Authorize(&_Payment.TransactOpts, _authorized, provider, podId) } -// CloseChannel is a paid mutator transaction binding the contract method 0x9e4ebce5. +// CloseChannel is a paid mutator transaction binding the contract method 0x0bbbd884. // -// Solidity: function closeChannel(address provider, bytes32 podId) returns() -func (_Payment *PaymentTransactor) CloseChannel(opts *bind.TransactOpts, provider common.Address, podId [32]byte) (*types.Transaction, error) { - return _Payment.contract.Transact(opts, "closeChannel", provider, podId) +// Solidity: function closeChannel(address publisher, address provider, bytes32 podId) returns() +func (_Payment *PaymentTransactor) CloseChannel(opts *bind.TransactOpts, publisher common.Address, provider common.Address, podId [32]byte) (*types.Transaction, error) { + return _Payment.contract.Transact(opts, "closeChannel", publisher, provider, podId) } -// CloseChannel is a paid mutator transaction binding the contract method 0x9e4ebce5. +// CloseChannel is a paid mutator transaction binding the contract method 0x0bbbd884. // -// Solidity: function closeChannel(address provider, bytes32 podId) returns() -func (_Payment *PaymentSession) CloseChannel(provider common.Address, podId [32]byte) (*types.Transaction, error) { - return _Payment.Contract.CloseChannel(&_Payment.TransactOpts, provider, podId) +// Solidity: function closeChannel(address publisher, address provider, bytes32 podId) returns() +func (_Payment *PaymentSession) CloseChannel(publisher common.Address, provider common.Address, podId [32]byte) (*types.Transaction, error) { + return _Payment.Contract.CloseChannel(&_Payment.TransactOpts, publisher, provider, podId) } -// CloseChannel is a paid mutator transaction binding the contract method 0x9e4ebce5. +// CloseChannel is a paid mutator transaction binding the contract method 0x0bbbd884. // -// Solidity: function closeChannel(address provider, bytes32 podId) returns() -func (_Payment *PaymentTransactorSession) CloseChannel(provider common.Address, podId [32]byte) (*types.Transaction, error) { - return _Payment.Contract.CloseChannel(&_Payment.TransactOpts, provider, podId) +// Solidity: function closeChannel(address publisher, address provider, bytes32 podId) returns() +func (_Payment *PaymentTransactorSession) CloseChannel(publisher common.Address, provider common.Address, podId [32]byte) (*types.Transaction, error) { + return _Payment.Contract.CloseChannel(&_Payment.TransactOpts, publisher, provider, podId) } // CreateChannel is a paid mutator transaction binding the contract method 0x744122b0. @@ -464,25 +464,25 @@ func (_Payment *PaymentTransactorSession) Deposit(provider common.Address, podId return _Payment.Contract.Deposit(&_Payment.TransactOpts, provider, podId, amount) } -// Unlock is a paid mutator transaction binding the contract method 0x785fd544. +// Unlock is a paid mutator transaction binding the contract method 0x77c5f23c. // -// Solidity: function unlock(address provider, bytes32 podId) returns() -func (_Payment *PaymentTransactor) Unlock(opts *bind.TransactOpts, provider common.Address, podId [32]byte) (*types.Transaction, error) { - return _Payment.contract.Transact(opts, "unlock", provider, podId) +// Solidity: function unlock(address publisher, address provider, bytes32 podId) returns() +func (_Payment *PaymentTransactor) Unlock(opts *bind.TransactOpts, publisher common.Address, provider common.Address, podId [32]byte) (*types.Transaction, error) { + return _Payment.contract.Transact(opts, "unlock", publisher, provider, podId) } -// Unlock is a paid mutator transaction binding the contract method 0x785fd544. +// Unlock is a paid mutator transaction binding the contract method 0x77c5f23c. // -// Solidity: function unlock(address provider, bytes32 podId) returns() -func (_Payment *PaymentSession) Unlock(provider common.Address, podId [32]byte) (*types.Transaction, error) { - return _Payment.Contract.Unlock(&_Payment.TransactOpts, provider, podId) +// Solidity: function unlock(address publisher, address provider, bytes32 podId) returns() +func (_Payment *PaymentSession) Unlock(publisher common.Address, provider common.Address, podId [32]byte) (*types.Transaction, error) { + return _Payment.Contract.Unlock(&_Payment.TransactOpts, publisher, provider, podId) } -// Unlock is a paid mutator transaction binding the contract method 0x785fd544. +// Unlock is a paid mutator transaction binding the contract method 0x77c5f23c. // -// Solidity: function unlock(address provider, bytes32 podId) returns() -func (_Payment *PaymentTransactorSession) Unlock(provider common.Address, podId [32]byte) (*types.Transaction, error) { - return _Payment.Contract.Unlock(&_Payment.TransactOpts, provider, podId) +// Solidity: function unlock(address publisher, address provider, bytes32 podId) returns() +func (_Payment *PaymentTransactorSession) Unlock(publisher common.Address, provider common.Address, podId [32]byte) (*types.Transaction, error) { + return _Payment.Contract.Unlock(&_Payment.TransactOpts, publisher, provider, podId) } // Withdraw is a paid mutator transaction binding the contract method 0x92a453a5. @@ -506,25 +506,25 @@ func (_Payment *PaymentTransactorSession) Withdraw(publisher common.Address, pod return _Payment.Contract.Withdraw(&_Payment.TransactOpts, publisher, podId, amount, transferAddress) } -// WithdrawUnlocked is a paid mutator transaction binding the contract method 0xb48b5e4b. +// WithdrawUnlocked is a paid mutator transaction binding the contract method 0x8e1577f4. // -// Solidity: function withdrawUnlocked(address provider, bytes32 podId) returns() -func (_Payment *PaymentTransactor) WithdrawUnlocked(opts *bind.TransactOpts, provider common.Address, podId [32]byte) (*types.Transaction, error) { - return _Payment.contract.Transact(opts, "withdrawUnlocked", provider, podId) +// Solidity: function withdrawUnlocked(address publisher, address provider, bytes32 podId) returns() +func (_Payment *PaymentTransactor) WithdrawUnlocked(opts *bind.TransactOpts, publisher common.Address, provider common.Address, podId [32]byte) (*types.Transaction, error) { + return _Payment.contract.Transact(opts, "withdrawUnlocked", publisher, provider, podId) } -// WithdrawUnlocked is a paid mutator transaction binding the contract method 0xb48b5e4b. +// WithdrawUnlocked is a paid mutator transaction binding the contract method 0x8e1577f4. // -// Solidity: function withdrawUnlocked(address provider, bytes32 podId) returns() -func (_Payment *PaymentSession) WithdrawUnlocked(provider common.Address, podId [32]byte) (*types.Transaction, error) { - return _Payment.Contract.WithdrawUnlocked(&_Payment.TransactOpts, provider, podId) +// Solidity: function withdrawUnlocked(address publisher, address provider, bytes32 podId) returns() +func (_Payment *PaymentSession) WithdrawUnlocked(publisher common.Address, provider common.Address, podId [32]byte) (*types.Transaction, error) { + return _Payment.Contract.WithdrawUnlocked(&_Payment.TransactOpts, publisher, provider, podId) } -// WithdrawUnlocked is a paid mutator transaction binding the contract method 0xb48b5e4b. +// WithdrawUnlocked is a paid mutator transaction binding the contract method 0x8e1577f4. // -// Solidity: function withdrawUnlocked(address provider, bytes32 podId) returns() -func (_Payment *PaymentTransactorSession) WithdrawUnlocked(provider common.Address, podId [32]byte) (*types.Transaction, error) { - return _Payment.Contract.WithdrawUnlocked(&_Payment.TransactOpts, provider, podId) +// Solidity: function withdrawUnlocked(address publisher, address provider, bytes32 podId) returns() +func (_Payment *PaymentTransactorSession) WithdrawUnlocked(publisher common.Address, provider common.Address, podId [32]byte) (*types.Transaction, error) { + return _Payment.Contract.WithdrawUnlocked(&_Payment.TransactOpts, publisher, provider, podId) } // WithdrawUpTo is a paid mutator transaction binding the contract method 0x494f8587. From 76cd691902184ac5b79084a3bfc39b24d06bf4dc Mon Sep 17 00:00:00 2001 From: revoltez Date: Thu, 1 Aug 2024 23:08:36 +0100 Subject: [PATCH 4/8] fix: new loki entry scheme --- cmd/trustedpods/log.go | 4 ++-- pkg/loki/loki.go | 28 +++++----------------------- 2 files changed, 7 insertions(+), 25 deletions(-) diff --git a/cmd/trustedpods/log.go b/cmd/trustedpods/log.go index 0edf13b9..17fdb639 100644 --- a/cmd/trustedpods/log.go +++ b/cmd/trustedpods/log.go @@ -21,7 +21,7 @@ var containerName string var logPodCmd = &cobra.Command{ Use: fmt.Sprintf("log [%s] [deployment.yaml]", publisher.DefaultPodFile), Short: "get pod container logs", - Args: cobra.ExactArgs(1), + Args: cobra.MaximumNArgs(2), GroupID: "main", RunE: func(cmd *cobra.Command, args []string) error { _, _, pod, deployment, err := publisher.ReadPodAndDeployment(args, manifestFormat, deploymentFormat) @@ -40,6 +40,7 @@ var logPodCmd = &cobra.Command{ } if publisherKey == "" { + fmt.Printf("publisherKey %v\n", publisherKey) publisherKey = common.BytesToAddress(deployment.Payment.PublisherAddress).String() } @@ -91,6 +92,5 @@ var logPodCmd = &cobra.Command{ func init() { podCmd.AddCommand(logPodCmd) - logPodCmd.Flags().AddFlagSet(deploymentFlags) logPodCmd.Flags().AddFlagSet(syncFlags) } diff --git a/pkg/loki/loki.go b/pkg/loki/loki.go index 138c8dd3..400fb7d0 100644 --- a/pkg/loki/loki.go +++ b/pkg/loki/loki.go @@ -14,7 +14,6 @@ import ( "connectrpc.com/connect" pb "github.com/comrade-coop/apocryph/pkg/proto" "github.com/gorilla/websocket" - "google.golang.org/protobuf/encoding/protojson" ) const tailPath = "/loki/api/v1/tail" @@ -106,13 +105,8 @@ func GetLogs(namespace, containerName, limit string, url string) ([]*pb.LogEntry func parseEntries(lines [][]string) ([]*pb.LogEntry, error) { logEntries := make([]*pb.LogEntry, len(lines)) for i, line := range lines { - logEntries[i] = &pb.LogEntry{} // inittialize the logEntry or it will cause null pointer dereference (i miss rust) - if err := protojson.Unmarshal([]byte(line[1]), logEntries[i]); err != nil { - fmt.Printf("Error unmarshalling entry:%v", err) - return nil, err - } - nanosecondsUnixEpoch, _ := strconv.ParseUint(line[0], 10, 64) + logEntries[i] = &pb.LogEntry{NanosecondsUnixEpoch: nanosecondsUnixEpoch, Line: line[1]} // inittialize the logEntry or it will cause null pointer dereference (i miss rust) logEntries[i].NanosecondsUnixEpoch = nanosecondsUnixEpoch } return logEntries, nil @@ -135,39 +129,27 @@ func GetStreamedEntries(namespace, containerName string, srv *connect.ServerStre c, _, err := websocket.DefaultDialer.Dial(requestURL, nil) if err != nil { - fmt.Println("Failed Dialing Server:", err) - return err + return fmt.Errorf("Failed Dialing Server:%v\n", err) } defer c.Close() for { var logs TailData err := c.ReadJSON(&logs) if err != nil { - fmt.Printf("Failed unmarshalling Json: %v \n", err) - return err + return fmt.Errorf("Failed unmarshalling Json: %v \n", err) } for _, result := range logs.Streams { entries, err := parseEntries(result.Values) if err != nil { - fmt.Println("Failed Parsing Entries:", err) - return err + return fmt.Errorf("Failed Parsing Entries:%v\n", err) } for _, entry := range entries { response := pb.PodLogResponse{} response.LogEntry = entry if err := srv.Send(&response); err != nil { - fmt.Printf("Error generating response: %v", err) - return err + return fmt.Errorf("Error generating response: %v\n", err) } } } } } - -// -// type LogEntry struct { -// NanosecondsUnixEpoch int64 `json:"nanoseconds_unix_epoch"` -// Log string `json:"log"` -// Stream string `json:"stream"` -// Time string `json:"time"` -// } From 78efafa167515b1e3090a5d48c30c35a7e10b476 Mon Sep 17 00:00:00 2001 From: revoltez Date: Thu, 1 Aug 2024 23:09:55 +0100 Subject: [PATCH 5/8] feat: generate keypair from the client side and send it encrypted Keypair is saved with encryption key in deployments --- cmd/trustedpods/deploy.go | 28 +- cmd/trustedpods/flags.go | 1 + pkg/autoscaler/server.go | 11 +- pkg/ethereum/client.go | 3 +- pkg/kubernetes/pods.go | 34 +-- pkg/proto-ts/deployment_pb.ts | 8 +- pkg/proto-ts/pod_pb.ts | 55 +++- pkg/proto-ts/provision-pod_pb.ts | 26 +- pkg/proto/deployment.pb.go | 108 ++++--- pkg/proto/pod.pb.go | 419 ++++++++++++++++---------- pkg/proto/provision-pod.pb.go | 113 +++---- pkg/provider/server.go | 1 - pkg/publisher/deployment.go | 107 ++++--- proto/deployment.proto | 2 + proto/pod.proto | 8 +- proto/provision-pod.proto | 5 +- test/e2e/autoscaler/run-test.sh | 10 +- test/e2e/autoscaler/start-clusters.sh | 5 + 18 files changed, 545 insertions(+), 399 deletions(-) create mode 100755 test/e2e/autoscaler/start-clusters.sh diff --git a/cmd/trustedpods/deploy.go b/cmd/trustedpods/deploy.go index 8b3778b3..44e871cf 100644 --- a/cmd/trustedpods/deploy.go +++ b/cmd/trustedpods/deploy.go @@ -3,11 +3,14 @@ package main import ( + "crypto/ecdsa" + "crypto/rand" "fmt" "math/big" "path/filepath" "github.com/comrade-coop/apocryph/pkg/abi" + tpcrypto "github.com/comrade-coop/apocryph/pkg/crypto" "github.com/comrade-coop/apocryph/pkg/ethereum" "github.com/comrade-coop/apocryph/pkg/ipcr" tpipfs "github.com/comrade-coop/apocryph/pkg/ipfs" @@ -16,6 +19,7 @@ import ( "github.com/comrade-coop/apocryph/pkg/publisher" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient" "github.com/ipfs/kubo/client/rpc" "github.com/spf13/cobra" @@ -95,7 +99,29 @@ var deployPodCmd = &cobra.Command{ configureDeployment(deployment) if authorize { - pod.Authorized = true + encryptionKey, err := tpcrypto.NewKey(tpcrypto.KeyTypeAESGCM256) + if err != nil { + return fmt.Errorf("Could not create AES key: %v", err) + } + // create the keypair that will be accessible for all pods + privateKey, err := ecdsa.GenerateKey(crypto.S256(), rand.Reader) + if err != nil { + return fmt.Errorf("Could not create private key for the application: %w", err) + } + // Ensure the public key is valid before getting the address + if privateKey == nil || privateKey.PublicKey.X == nil || privateKey.PublicKey.Y == nil { + return fmt.Errorf("Generated an invalid public key") + } + + pubAddress := crypto.PubkeyToAddress(privateKey.PublicKey) + + encryptedPrivateKey, err := tpcrypto.EncryptWithKey(encryptionKey, crypto.FromECDSA(privateKey)) + if err != nil { + return fmt.Errorf("Could not encrypt private key: %v", err) + } + + pod.KeyPair = &pb.KeyPair{Key: encryptionKey, PrivateKey: encryptedPrivateKey, PubAddress: pubAddress.Hex()} + deployment.KeyPair = pod.KeyPair } fundsInt, _ := (&big.Int{}).SetString(funds, 10) diff --git a/cmd/trustedpods/flags.go b/cmd/trustedpods/flags.go index b54ac4f5..c9a7eb78 100644 --- a/cmd/trustedpods/flags.go +++ b/cmd/trustedpods/flags.go @@ -75,6 +75,7 @@ var _ = func() error { fundFlags.Int64Var(&unlockTime, "unlock-time", 5*60, "time for unlocking tokens (in seconds)") syncFlags.AddFlag(uploadFlags.Lookup("ipfs")) + syncFlags.StringVar(&publisherKey, "ethereum-key", "", "account string (private key | http[s]://clef#account | /keystore#account | account (in default keystore))") registryFlags.StringVar(&ipfsApi, "ipfs", "/ip4/127.0.0.1/tcp/5001", "multiaddr where the ipfs/kubo api can be accessed") registryFlags.StringVar(®istryContractAddress, "registry-contract", "", "registry contract address") diff --git a/pkg/autoscaler/server.go b/pkg/autoscaler/server.go index 4e71a926..fa12020a 100644 --- a/pkg/autoscaler/server.go +++ b/pkg/autoscaler/server.go @@ -156,7 +156,14 @@ func (s *AutoScalerServer) BoostrapCluster(req *connect.Request[pb.ConnectCluste func (s *AutoScalerServer) ConnectCluster(c context.Context, req *connect.Request[pb.ConnectClusterRequest]) (*connect.Response[pb.ConnectClusterResponse], error) { log.Println("Forming a Raft Cluster with the following providers:", req.Msg.Servers) - s.started = true + + if s.started == true { + return connect.NewResponse(&pb.ConnectClusterResponse{ + Success: false, + Error: "Server Already Started\n", + }), nil + } + err := s.BoostrapCluster(req) if err != nil { return connect.NewResponse(&pb.ConnectClusterResponse{ @@ -164,6 +171,8 @@ func (s *AutoScalerServer) ConnectCluster(c context.Context, req *connect.Reques Error: fmt.Sprintf("Failed Bootstraping Cluster: %v\n", err), }), nil } + + s.started = true response := &pb.ConnectClusterResponse{Success: true} return connect.NewResponse(response), nil } diff --git a/pkg/ethereum/client.go b/pkg/ethereum/client.go index e63e19ce..fddde32e 100644 --- a/pkg/ethereum/client.go +++ b/pkg/ethereum/client.go @@ -126,8 +126,7 @@ func GetAccountAndSigner(accountString string, client *ethclient.Client) (*bind. } } -func EncodePrivateKey(privateKey *ecdsa.PrivateKey) (string, error) { - privateKeyBytes := crypto.FromECDSA(privateKey) +func EncodePrivateKey(privateKeyBytes []byte) (string, error) { return hex.EncodeToString(privateKeyBytes), nil } diff --git a/pkg/kubernetes/pods.go b/pkg/kubernetes/pods.go index 449441ad..e2b51584 100644 --- a/pkg/kubernetes/pods.go +++ b/pkg/kubernetes/pods.go @@ -4,16 +4,14 @@ package kubernetes import ( "context" - "crypto/ecdsa" - "crypto/rand" "fmt" "strings" "github.com/comrade-coop/apocryph/pkg/constants" + tpcrypto "github.com/comrade-coop/apocryph/pkg/crypto" "github.com/comrade-coop/apocryph/pkg/ethereum" pb "github.com/comrade-coop/apocryph/pkg/proto" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" kedahttpv1alpha1 "github.com/kedacore/http-add-on/operator/apis/http/v1alpha1" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -99,22 +97,6 @@ func ApplyPodRequest( }, }, } - var privateKey *ecdsa.PrivateKey - var address common.Address - - if podManifest.Authorized == true { - // create the keypair that will be accessible for all pods - var err error - privateKey, err = ecdsa.GenerateKey(crypto.S256(), rand.Reader) - if err != nil { - return fmt.Errorf("Could not create private key for the application: %w", err) - } - // Ensure the public key is valid before getting the address - if privateKey == nil || privateKey.PublicKey.X == nil || privateKey.PublicKey.Y == nil { - return fmt.Errorf("Generated an invalid public key") - } - address = crypto.PubkeyToAddress(privateKey.PublicKey) - } podTemplate := &deployment.Spec.Template @@ -133,13 +115,17 @@ func ApplyPodRequest( WorkingDir: container.WorkingDir, } - if podManifest.Authorized { + if podManifest.KeyPair != nil { + privatekey, err := tpcrypto.DecryptWithKey(podManifest.KeyPair.Key, podManifest.KeyPair.PrivateKey) + if err != nil { + return fmt.Errorf("Failed Decrypting private key: %v\n", err) + } - key, err := ethereum.EncodePrivateKey(privateKey) + key, err := ethereum.EncodePrivateKey(privatekey) if err != nil { return fmt.Errorf("Failed encoding private key: %v\n", err) } - fmt.Println("Setting Env variables:") + containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: constants.PRIVATE_KEY, Value: key}) // save as hex to parse later as hex containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: constants.PAYMENT_ADDR_KEY, Value: common.BytesToAddress(paymentChannel.ContractAddress).Hex()}) @@ -147,9 +133,7 @@ func ApplyPodRequest( containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: constants.PROVIDER_ADDR_KEY, Value: common.BytesToAddress(paymentChannel.ProviderAddress).Hex()}) containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: constants.POD_ID_KEY, Value: common.BytesToHash(paymentChannel.PodID).Hex()}) containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: constants.PRIVATE_KEY, Value: key}) - containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: constants.PUBLIC_ADDRESS_KEY, Value: address.Hex()}) - - response.PubAddress = address.Hex() + containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: constants.PUBLIC_ADDRESS_KEY, Value: podManifest.KeyPair.PubAddress}) } for field, value := range container.Env { diff --git a/pkg/proto-ts/deployment_pb.ts b/pkg/proto-ts/deployment_pb.ts index a3ce6995..dc452c16 100644 --- a/pkg/proto-ts/deployment_pb.ts +++ b/pkg/proto-ts/deployment_pb.ts @@ -8,7 +8,7 @@ import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf"; import { Message, proto3 } from "@bufbuild/protobuf"; import { ProvisionPodResponse } from "./provision-pod_pb.js"; -import { Key } from "./pod_pb.js"; +import { Key, KeyPair } from "./pod_pb.js"; /** * @generated from message apocryph.proto.v0.deployment.Deployment @@ -44,6 +44,11 @@ export class Deployment extends Message { */ deployed?: ProvisionPodResponse; + /** + * @generated from field: apocryph.proto.v0.pod.KeyPair keyPair = 7; + */ + keyPair?: KeyPair; + constructor(data?: PartialMessage) { super(); proto3.util.initPartial(data, this); @@ -58,6 +63,7 @@ export class Deployment extends Message { { no: 4, name: "images", kind: "message", T: UploadedImage, repeated: true }, { no: 5, name: "secrets", kind: "message", T: UploadedSecret, repeated: true }, { no: 6, name: "deployed", kind: "message", T: ProvisionPodResponse }, + { no: 7, name: "keyPair", kind: "message", T: KeyPair }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): Deployment { diff --git a/pkg/proto-ts/pod_pb.ts b/pkg/proto-ts/pod_pb.ts index 03ec0002..b89030fb 100644 --- a/pkg/proto-ts/pod_pb.ts +++ b/pkg/proto-ts/pod_pb.ts @@ -28,9 +28,9 @@ export class Pod extends Message { replicas?: Replicas; /** - * @generated from field: bool authorized = 4; + * @generated from field: apocryph.proto.v0.pod.KeyPair keyPair = 4; */ - authorized = false; + keyPair?: KeyPair; constructor(data?: PartialMessage) { super(); @@ -43,7 +43,7 @@ export class Pod extends Message { { no: 1, name: "containers", kind: "message", T: Container, repeated: true }, { no: 2, name: "volumes", kind: "message", T: Volume, repeated: true }, { no: 3, name: "replicas", kind: "message", T: Replicas }, - { no: 4, name: "authorized", kind: "scalar", T: 8 /* ScalarType.BOOL */ }, + { no: 4, name: "keyPair", kind: "message", T: KeyPair }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): Pod { @@ -679,3 +679,52 @@ export class Key extends Message { } } +/** + * @generated from message apocryph.proto.v0.pod.KeyPair + */ +export class KeyPair extends Message { + /** + * @generated from field: apocryph.proto.v0.pod.Key key = 1; + */ + key?: Key; + + /** + * @generated from field: bytes privateKey = 2; + */ + privateKey = new Uint8Array(0); + + /** + * @generated from field: string pubAddress = 3; + */ + pubAddress = ""; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "apocryph.proto.v0.pod.KeyPair"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "key", kind: "message", T: Key }, + { no: 2, name: "privateKey", kind: "scalar", T: 12 /* ScalarType.BYTES */ }, + { no: 3, name: "pubAddress", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): KeyPair { + return new KeyPair().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): KeyPair { + return new KeyPair().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): KeyPair { + return new KeyPair().fromJsonString(jsonString, options); + } + + static equals(a: KeyPair | PlainMessage | undefined, b: KeyPair | PlainMessage | undefined): boolean { + return proto3.util.equals(KeyPair, a, b); + } +} + diff --git a/pkg/proto-ts/provision-pod_pb.ts b/pkg/proto-ts/provision-pod_pb.ts index 60238efe..2fa83ceb 100644 --- a/pkg/proto-ts/provision-pod_pb.ts +++ b/pkg/proto-ts/provision-pod_pb.ts @@ -292,11 +292,6 @@ export class ProvisionPodResponse extends Message { */ namespace = ""; - /** - * @generated from field: string pubAddress = 4; - */ - pubAddress = ""; - constructor(data?: PartialMessage) { super(); proto3.util.initPartial(data, this); @@ -308,7 +303,6 @@ export class ProvisionPodResponse extends Message { { no: 1, name: "error", kind: "scalar", T: 9 /* ScalarType.STRING */ }, { no: 2, name: "addresses", kind: "message", T: ProvisionPodResponse_ExposedHostPort, repeated: true }, { no: 3, name: "namespace", kind: "scalar", T: 9 /* ScalarType.STRING */ }, - { no: 4, name: "pubAddress", kind: "scalar", T: 9 /* ScalarType.STRING */ }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): ProvisionPodResponse { @@ -461,21 +455,9 @@ export class LogEntry extends Message { NanosecondsUnixEpoch = protoInt64.zero; /** - * @generated from field: string log = 2; - */ - log = ""; - - /** - * std(in/out/err) - * - * @generated from field: string stream = 3; - */ - stream = ""; - - /** - * @generated from field: string time = 4; + * @generated from field: string line = 2; */ - time = ""; + line = ""; constructor(data?: PartialMessage) { super(); @@ -486,9 +468,7 @@ export class LogEntry extends Message { static readonly typeName = "apocryph.proto.v0.provisionPod.LogEntry"; static readonly fields: FieldList = proto3.util.newFieldList(() => [ { no: 1, name: "NanosecondsUnixEpoch", kind: "scalar", T: 4 /* ScalarType.UINT64 */ }, - { no: 2, name: "log", kind: "scalar", T: 9 /* ScalarType.STRING */ }, - { no: 3, name: "stream", kind: "scalar", T: 9 /* ScalarType.STRING */ }, - { no: 4, name: "time", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 2, name: "line", kind: "scalar", T: 9 /* ScalarType.STRING */ }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): LogEntry { diff --git a/pkg/proto/deployment.pb.go b/pkg/proto/deployment.pb.go index 1eef0a24..737a7da5 100644 --- a/pkg/proto/deployment.pb.go +++ b/pkg/proto/deployment.pb.go @@ -33,6 +33,7 @@ type Deployment struct { Images []*UploadedImage `protobuf:"bytes,4,rep,name=images,proto3" json:"images,omitempty"` Secrets []*UploadedSecret `protobuf:"bytes,5,rep,name=secrets,proto3" json:"secrets,omitempty"` Deployed *ProvisionPodResponse `protobuf:"bytes,6,opt,name=deployed,proto3" json:"deployed,omitempty"` + KeyPair *KeyPair `protobuf:"bytes,7,opt,name=keyPair,proto3" json:"keyPair,omitempty"` } func (x *Deployment) Reset() { @@ -109,6 +110,13 @@ func (x *Deployment) GetDeployed() *ProvisionPodResponse { return nil } +func (x *Deployment) GetKeyPair() *KeyPair { + if x != nil { + return x.KeyPair + } + return nil +} + type ProviderConfig struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -385,7 +393,7 @@ var file_deployment_proto_rawDesc = []byte{ 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x1a, 0x13, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2d, 0x70, 0x6f, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x09, 0x70, 0x6f, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x22, 0xad, 0x03, 0x0a, 0x0a, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, + 0x22, 0xe7, 0x03, 0x0a, 0x0a, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x70, 0x6f, 0x64, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x6f, 0x64, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x48, 0x0a, 0x08, 0x70, 0x72, 0x6f, @@ -412,44 +420,48 @@ var file_deployment_proto_rawDesc = []byte{ 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, - 0x22, 0x60, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x12, 0x28, 0x0a, 0x0f, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x41, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x65, 0x74, 0x68, - 0x65, 0x72, 0x65, 0x75, 0x6d, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x24, 0x0a, 0x0d, - 0x6c, 0x69, 0x62, 0x70, 0x32, 0x70, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6c, 0x69, 0x62, 0x70, 0x32, 0x70, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x22, 0xaa, 0x01, 0x0a, 0x14, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x68, - 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x49, 0x44, 0x12, 0x36, 0x0a, 0x16, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, - 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x16, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x6f, - 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x2a, 0x0a, - 0x10, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, - 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x6f, 0x64, - 0x49, 0x44, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x70, 0x6f, 0x64, 0x49, 0x44, 0x22, - 0x85, 0x01, 0x0a, 0x0d, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x49, 0x6d, 0x61, 0x67, - 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x72, 0x6c, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x72, 0x6c, 0x12, - 0x16, 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x69, 0x64, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x63, 0x69, 0x64, 0x12, 0x2c, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, - 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x4b, - 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x8e, 0x01, 0x0a, 0x0e, 0x55, 0x70, 0x6c, 0x6f, - 0x61, 0x64, 0x65, 0x64, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x76, 0x6f, - 0x6c, 0x75, 0x6d, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x68, - 0x61, 0x32, 0x35, 0x36, 0x73, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, - 0x68, 0x61, 0x32, 0x35, 0x36, 0x73, 0x75, 0x6d, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x69, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x63, 0x69, 0x64, 0x12, 0x2c, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, - 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, - 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6d, 0x72, 0x61, 0x64, 0x65, 0x2d, 0x63, - 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2f, 0x70, 0x6b, 0x67, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x12, 0x38, 0x0a, 0x07, 0x6b, 0x65, 0x79, 0x50, 0x61, 0x69, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1e, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x4b, 0x65, 0x79, 0x50, 0x61, 0x69, + 0x72, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x50, 0x61, 0x69, 0x72, 0x22, 0x60, 0x0a, 0x0e, 0x50, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x28, 0x0a, 0x0f, + 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x6c, 0x69, 0x62, 0x70, 0x32, 0x70, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6c, + 0x69, 0x62, 0x70, 0x32, 0x70, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0xaa, 0x01, 0x0a, + 0x14, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x12, + 0x36, 0x0a, 0x16, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, + 0x63, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x16, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x70, 0x75, 0x62, 0x6c, 0x69, + 0x73, 0x68, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x10, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x6f, 0x64, 0x49, 0x44, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x05, 0x70, 0x6f, 0x64, 0x49, 0x44, 0x22, 0x85, 0x01, 0x0a, 0x0d, 0x55, 0x70, + 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x69, 0x67, + 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, + 0x74, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, + 0x63, 0x69, 0x64, 0x12, 0x2c, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x22, 0x8e, 0x01, 0x0a, 0x0e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x53, 0x65, + 0x63, 0x72, 0x65, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x4e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x73, 0x75, + 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x73, + 0x75, 0x6d, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x03, 0x63, 0x69, 0x64, 0x12, 0x2c, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x63, 0x6f, 0x6d, 0x72, 0x61, 0x64, 0x65, 0x2d, 0x63, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, + 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -472,7 +484,8 @@ var file_deployment_proto_goTypes = []interface{}{ (*UploadedImage)(nil), // 3: apocryph.proto.v0.deployment.UploadedImage (*UploadedSecret)(nil), // 4: apocryph.proto.v0.deployment.UploadedSecret (*ProvisionPodResponse)(nil), // 5: apocryph.proto.v0.provisionPod.ProvisionPodResponse - (*Key)(nil), // 6: apocryph.proto.v0.pod.Key + (*KeyPair)(nil), // 6: apocryph.proto.v0.pod.KeyPair + (*Key)(nil), // 7: apocryph.proto.v0.pod.Key } var file_deployment_proto_depIdxs = []int32{ 1, // 0: apocryph.proto.v0.deployment.Deployment.provider:type_name -> apocryph.proto.v0.deployment.ProviderConfig @@ -480,13 +493,14 @@ var file_deployment_proto_depIdxs = []int32{ 3, // 2: apocryph.proto.v0.deployment.Deployment.images:type_name -> apocryph.proto.v0.deployment.UploadedImage 4, // 3: apocryph.proto.v0.deployment.Deployment.secrets:type_name -> apocryph.proto.v0.deployment.UploadedSecret 5, // 4: apocryph.proto.v0.deployment.Deployment.deployed:type_name -> apocryph.proto.v0.provisionPod.ProvisionPodResponse - 6, // 5: apocryph.proto.v0.deployment.UploadedImage.key:type_name -> apocryph.proto.v0.pod.Key - 6, // 6: apocryph.proto.v0.deployment.UploadedSecret.key:type_name -> apocryph.proto.v0.pod.Key - 7, // [7:7] is the sub-list for method output_type - 7, // [7:7] is the sub-list for method input_type - 7, // [7:7] is the sub-list for extension type_name - 7, // [7:7] is the sub-list for extension extendee - 0, // [0:7] is the sub-list for field type_name + 6, // 5: apocryph.proto.v0.deployment.Deployment.keyPair:type_name -> apocryph.proto.v0.pod.KeyPair + 7, // 6: apocryph.proto.v0.deployment.UploadedImage.key:type_name -> apocryph.proto.v0.pod.Key + 7, // 7: apocryph.proto.v0.deployment.UploadedSecret.key:type_name -> apocryph.proto.v0.pod.Key + 8, // [8:8] is the sub-list for method output_type + 8, // [8:8] is the sub-list for method input_type + 8, // [8:8] is the sub-list for extension type_name + 8, // [8:8] is the sub-list for extension extendee + 0, // [0:8] is the sub-list for field type_name } func init() { file_deployment_proto_init() } diff --git a/pkg/proto/pod.pb.go b/pkg/proto/pod.pb.go index cfa69d68..32e21b7a 100644 --- a/pkg/proto/pod.pb.go +++ b/pkg/proto/pod.pb.go @@ -126,7 +126,7 @@ type Pod struct { Containers []*Container `protobuf:"bytes,1,rep,name=containers,proto3" json:"containers,omitempty"` Volumes []*Volume `protobuf:"bytes,2,rep,name=volumes,proto3" json:"volumes,omitempty"` Replicas *Replicas `protobuf:"bytes,3,opt,name=replicas,proto3" json:"replicas,omitempty"` - Authorized bool `protobuf:"varint,4,opt,name=authorized,proto3" json:"authorized,omitempty"` + KeyPair *KeyPair `protobuf:"bytes,4,opt,name=keyPair,proto3" json:"keyPair,omitempty"` } func (x *Pod) Reset() { @@ -182,11 +182,11 @@ func (x *Pod) GetReplicas() *Replicas { return nil } -func (x *Pod) GetAuthorized() bool { +func (x *Pod) GetKeyPair() *KeyPair { if x != nil { - return x.Authorized + return x.KeyPair } - return false + return nil } type Container struct { @@ -604,6 +604,69 @@ func (x *Key) GetData() []byte { return nil } +type KeyPair struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key *Key `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + PrivateKey []byte `protobuf:"bytes,2,opt,name=privateKey,proto3" json:"privateKey,omitempty"` + PubAddress string `protobuf:"bytes,3,opt,name=pubAddress,proto3" json:"pubAddress,omitempty"` +} + +func (x *KeyPair) Reset() { + *x = KeyPair{} + if protoimpl.UnsafeEnabled { + mi := &file_pod_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *KeyPair) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*KeyPair) ProtoMessage() {} + +func (x *KeyPair) ProtoReflect() protoreflect.Message { + mi := &file_pod_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use KeyPair.ProtoReflect.Descriptor instead. +func (*KeyPair) Descriptor() ([]byte, []int) { + return file_pod_proto_rawDescGZIP(), []int{6} +} + +func (x *KeyPair) GetKey() *Key { + if x != nil { + return x.Key + } + return nil +} + +func (x *KeyPair) GetPrivateKey() []byte { + if x != nil { + return x.PrivateKey + } + return nil +} + +func (x *KeyPair) GetPubAddress() string { + if x != nil { + return x.PubAddress + } + return "" +} + type Container_Image struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -617,7 +680,7 @@ type Container_Image struct { func (x *Container_Image) Reset() { *x = Container_Image{} if protoimpl.UnsafeEnabled { - mi := &file_pod_proto_msgTypes[7] + mi := &file_pod_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -630,7 +693,7 @@ func (x *Container_Image) String() string { func (*Container_Image) ProtoMessage() {} func (x *Container_Image) ProtoReflect() protoreflect.Message { - mi := &file_pod_proto_msgTypes[7] + mi := &file_pod_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -685,7 +748,7 @@ type Container_Port struct { func (x *Container_Port) Reset() { *x = Container_Port{} if protoimpl.UnsafeEnabled { - mi := &file_pod_proto_msgTypes[8] + mi := &file_pod_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -698,7 +761,7 @@ func (x *Container_Port) String() string { func (*Container_Port) ProtoMessage() {} func (x *Container_Port) ProtoReflect() protoreflect.Message { - mi := &file_pod_proto_msgTypes[8] + mi := &file_pod_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -786,7 +849,7 @@ type Container_VolumeMount struct { func (x *Container_VolumeMount) Reset() { *x = Container_VolumeMount{} if protoimpl.UnsafeEnabled { - mi := &file_pod_proto_msgTypes[9] + mi := &file_pod_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -799,7 +862,7 @@ func (x *Container_VolumeMount) String() string { func (*Container_VolumeMount) ProtoMessage() {} func (x *Container_VolumeMount) ProtoReflect() protoreflect.Message { - mi := &file_pod_proto_msgTypes[9] + mi := &file_pod_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -847,7 +910,7 @@ type Volume_FilesystemConfig struct { func (x *Volume_FilesystemConfig) Reset() { *x = Volume_FilesystemConfig{} if protoimpl.UnsafeEnabled { - mi := &file_pod_proto_msgTypes[10] + mi := &file_pod_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -860,7 +923,7 @@ func (x *Volume_FilesystemConfig) String() string { func (*Volume_FilesystemConfig) ProtoMessage() {} func (x *Volume_FilesystemConfig) ProtoReflect() protoreflect.Message { - mi := &file_pod_proto_msgTypes[10] + mi := &file_pod_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -898,7 +961,7 @@ type Volume_SecretConfig struct { func (x *Volume_SecretConfig) Reset() { *x = Volume_SecretConfig{} if protoimpl.UnsafeEnabled { - mi := &file_pod_proto_msgTypes[11] + mi := &file_pod_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -911,7 +974,7 @@ func (x *Volume_SecretConfig) String() string { func (*Volume_SecretConfig) ProtoMessage() {} func (x *Volume_SecretConfig) ProtoReflect() protoreflect.Message { - mi := &file_pod_proto_msgTypes[11] + mi := &file_pod_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -967,7 +1030,7 @@ var File_pod_proto protoreflect.FileDescriptor var file_pod_proto_rawDesc = []byte{ 0x0a, 0x09, 0x70, 0x6f, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x15, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, - 0x6f, 0x64, 0x22, 0xdd, 0x01, 0x0a, 0x03, 0x50, 0x6f, 0x64, 0x12, 0x40, 0x0a, 0x0a, 0x63, 0x6f, + 0x6f, 0x64, 0x22, 0xf7, 0x01, 0x0a, 0x03, 0x50, 0x6f, 0x64, 0x12, 0x40, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, @@ -979,128 +1042,137 @@ var file_pod_proto_rawDesc = []byte{ 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x52, 0x08, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, - 0x65, 0x64, 0x22, 0xf4, 0x06, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3c, 0x0a, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x43, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x05, 0x69, 0x6d, 0x61, - 0x67, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x70, 0x6f, 0x69, 0x6e, 0x74, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x70, 0x6f, 0x69, - 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x1e, 0x0a, 0x0a, - 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x44, 0x69, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0a, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x44, 0x69, 0x72, 0x12, 0x3b, 0x0a, 0x05, - 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x61, 0x70, - 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, - 0x70, 0x6f, 0x64, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x6f, - 0x72, 0x74, 0x52, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x3b, 0x0a, 0x03, 0x65, 0x6e, 0x76, - 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, - 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x43, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x45, 0x6e, 0x76, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x52, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x46, 0x0a, 0x07, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, - 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, - 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, - 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, - 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x07, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x73, 0x12, 0x4b, - 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, + 0x61, 0x73, 0x12, 0x38, 0x0a, 0x07, 0x6b, 0x65, 0x79, 0x50, 0x61, 0x69, 0x72, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x4b, 0x65, 0x79, 0x50, + 0x61, 0x69, 0x72, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x50, 0x61, 0x69, 0x72, 0x22, 0xf4, 0x06, 0x0a, + 0x09, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3c, + 0x0a, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, + 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, + 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, + 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x1e, 0x0a, 0x0a, + 0x65, 0x6e, 0x74, 0x72, 0x79, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x0a, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, + 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x63, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, + 0x67, 0x44, 0x69, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x77, 0x6f, 0x72, 0x6b, + 0x69, 0x6e, 0x67, 0x44, 0x69, 0x72, 0x12, 0x3b, 0x0a, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, + 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x43, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x05, 0x70, 0x6f, + 0x72, 0x74, 0x73, 0x12, 0x3b, 0x0a, 0x03, 0x65, 0x6e, 0x76, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x29, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x2e, 0x45, 0x6e, 0x76, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x03, 0x65, 0x6e, 0x76, + 0x12, 0x46, 0x0a, 0x07, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x2c, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x2e, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x52, + 0x07, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x73, 0x12, 0x4b, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x09, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x52, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x73, 0x1a, 0x36, 0x0a, 0x08, 0x45, 0x6e, 0x76, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x59, 0x0a, + 0x05, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x03, 0x63, 0x69, 0x64, 0x12, 0x2c, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x4b, 0x65, + 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x1a, 0xbb, 0x01, 0x0a, 0x04, 0x50, 0x6f, 0x72, + 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x24, 0x0a, + 0x0c, 0x68, 0x6f, 0x73, 0x74, 0x48, 0x74, 0x74, 0x70, 0x48, 0x6f, 0x73, 0x74, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0c, 0x68, 0x6f, 0x73, 0x74, 0x48, 0x74, 0x74, 0x70, 0x48, + 0x6f, 0x73, 0x74, 0x12, 0x22, 0x0a, 0x0b, 0x68, 0x6f, 0x73, 0x74, 0x54, 0x63, 0x70, 0x50, 0x6f, + 0x72, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, 0x0b, 0x68, 0x6f, 0x73, 0x74, + 0x54, 0x63, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x42, 0x0d, 0x0a, 0x0b, 0x65, 0x78, 0x70, 0x6f, 0x73, + 0x65, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x1a, 0x5b, 0x0a, 0x0b, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, + 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6d, 0x6f, 0x75, + 0x6e, 0x74, 0x50, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x61, 0x64, 0x4f, + 0x6e, 0x6c, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x61, 0x64, 0x4f, + 0x6e, 0x6c, 0x79, 0x22, 0xca, 0x05, 0x0a, 0x06, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x22, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x48, 0x0a, 0x0a, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, + 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x76, 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x50, 0x0a, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x6f, 0x64, - 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x1a, 0x36, 0x0a, 0x08, 0x45, - 0x6e, 0x76, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, - 0x02, 0x38, 0x01, 0x1a, 0x59, 0x0a, 0x05, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x10, 0x0a, 0x03, - 0x63, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x63, 0x69, 0x64, 0x12, 0x2c, - 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x61, 0x70, - 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, - 0x70, 0x6f, 0x64, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, - 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x1a, 0xbb, - 0x01, 0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x50, 0x6f, 0x72, - 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, - 0x6f, 0x72, 0x74, 0x12, 0x24, 0x0a, 0x0c, 0x68, 0x6f, 0x73, 0x74, 0x48, 0x74, 0x74, 0x70, 0x48, - 0x6f, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0c, 0x68, 0x6f, 0x73, - 0x74, 0x48, 0x74, 0x74, 0x70, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x22, 0x0a, 0x0b, 0x68, 0x6f, 0x73, - 0x74, 0x54, 0x63, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, - 0x52, 0x0b, 0x68, 0x6f, 0x73, 0x74, 0x54, 0x63, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x42, 0x0d, 0x0a, - 0x0b, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x1a, 0x5b, 0x0a, 0x0b, - 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, - 0x1c, 0x0a, 0x09, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1a, 0x0a, - 0x08, 0x72, 0x65, 0x61, 0x64, 0x4f, 0x6e, 0x6c, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x08, 0x72, 0x65, 0x61, 0x64, 0x4f, 0x6e, 0x6c, 0x79, 0x22, 0xca, 0x05, 0x0a, 0x06, 0x56, 0x6f, - 0x6c, 0x75, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, + 0x2e, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x65, + 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x44, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x56, - 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x12, 0x48, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x56, 0x6f, 0x6c, - 0x75, 0x6d, 0x65, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x0a, - 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x50, 0x0a, 0x0a, 0x66, 0x69, - 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, - 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, - 0x76, 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x46, 0x69, - 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, - 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x44, 0x0a, 0x06, - 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x61, - 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, - 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x53, 0x65, 0x63, 0x72, - 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, - 0x65, 0x74, 0x1a, 0x5f, 0x0a, 0x10, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4b, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x1f, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x52, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x73, 0x1a, 0xa6, 0x01, 0x0a, 0x0c, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x03, 0x63, 0x69, 0x64, 0x12, 0x2c, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x4b, 0x65, 0x79, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x65, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x73, 0x18, 0x66, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, - 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x67, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x42, 0x0a, 0x04, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x0c, 0x56, 0x4f, 0x4c, 0x55, 0x4d, 0x45, 0x5f, 0x45, - 0x4d, 0x50, 0x54, 0x59, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4f, 0x4c, 0x55, 0x4d, 0x45, - 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x10, 0x01, 0x12, 0x11, 0x0a, - 0x0d, 0x56, 0x4f, 0x4c, 0x55, 0x4d, 0x45, 0x5f, 0x53, 0x45, 0x43, 0x52, 0x45, 0x54, 0x10, 0x02, - 0x22, 0x33, 0x0a, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x11, - 0x0a, 0x0d, 0x56, 0x4f, 0x4c, 0x55, 0x4d, 0x45, 0x5f, 0x52, 0x57, 0x5f, 0x4f, 0x4e, 0x45, 0x10, - 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x56, 0x4f, 0x4c, 0x55, 0x4d, 0x45, 0x5f, 0x52, 0x57, 0x5f, 0x4d, - 0x41, 0x4e, 0x59, 0x10, 0x02, 0x42, 0x0f, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x64, 0x0a, 0x08, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x03, 0x6d, 0x69, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x61, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x03, 0x6d, 0x61, 0x78, 0x12, 0x34, 0x0a, 0x15, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x15, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x50, 0x65, 0x6e, - 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x22, 0x72, 0x0a, 0x08, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x24, - 0x0a, 0x0c, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, 0x0c, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x69, - 0x6c, 0x6c, 0x69, 0x73, 0x42, 0x0a, 0x0a, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x22, 0x19, 0x0a, 0x03, 0x4b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x42, 0x2c, 0x5a, 0x2a, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6d, 0x72, 0x61, 0x64, - 0x65, 0x2d, 0x63, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2f, - 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x48, 0x00, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x1a, 0x5f, 0x0a, 0x10, + 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x12, 0x4b, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x61, 0x70, 0x6f, + 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, + 0x6f, 0x64, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x10, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x1a, 0xa6, 0x01, + 0x0a, 0x0c, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, + 0x0a, 0x03, 0x63, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x63, 0x69, 0x64, + 0x12, 0x2c, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, + 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x12, + 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x65, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, + 0x6c, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x66, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x26, + 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x18, 0x67, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x42, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x10, + 0x0a, 0x0c, 0x56, 0x4f, 0x4c, 0x55, 0x4d, 0x45, 0x5f, 0x45, 0x4d, 0x50, 0x54, 0x59, 0x10, 0x00, + 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4f, 0x4c, 0x55, 0x4d, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x53, + 0x59, 0x53, 0x54, 0x45, 0x4d, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x56, 0x4f, 0x4c, 0x55, 0x4d, + 0x45, 0x5f, 0x53, 0x45, 0x43, 0x52, 0x45, 0x54, 0x10, 0x02, 0x22, 0x33, 0x0a, 0x0a, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x11, 0x0a, 0x0d, 0x56, 0x4f, 0x4c, 0x55, + 0x4d, 0x45, 0x5f, 0x52, 0x57, 0x5f, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x56, + 0x4f, 0x4c, 0x55, 0x4d, 0x45, 0x5f, 0x52, 0x57, 0x5f, 0x4d, 0x41, 0x4e, 0x59, 0x10, 0x02, 0x42, + 0x0f, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x22, 0x64, 0x0a, 0x08, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x12, 0x10, 0x0a, 0x03, + 0x6d, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6d, 0x69, 0x6e, 0x12, 0x10, + 0x0a, 0x03, 0x6d, 0x61, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6d, 0x61, 0x78, + 0x12, 0x34, 0x0a, 0x15, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, + 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x15, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x22, 0x72, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x18, + 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, + 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0c, 0x61, 0x6d, 0x6f, 0x75, + 0x6e, 0x74, 0x4d, 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, + 0x52, 0x0c, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x42, 0x0a, + 0x0a, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x19, 0x0a, 0x03, 0x4b, 0x65, + 0x79, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x77, 0x0a, 0x07, 0x4b, 0x65, 0x79, 0x50, 0x61, 0x69, 0x72, + 0x12, 0x2c, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, + 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x1e, + 0x0a, 0x0a, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1e, + 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x70, 0x75, 0x62, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x2c, + 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6d, + 0x72, 0x61, 0x64, 0x65, 0x2d, 0x63, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, + 0x70, 0x68, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1116,7 +1188,7 @@ func file_pod_proto_rawDescGZIP() []byte { } var file_pod_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_pod_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_pod_proto_msgTypes = make([]protoimpl.MessageInfo, 13) var file_pod_proto_goTypes = []interface{}{ (Volume_Type)(0), // 0: apocryph.proto.v0.pod.Volume.Type (Volume_AccessMode)(0), // 1: apocryph.proto.v0.pod.Volume.AccessMode @@ -1126,34 +1198,37 @@ var file_pod_proto_goTypes = []interface{}{ (*Replicas)(nil), // 5: apocryph.proto.v0.pod.Replicas (*Resource)(nil), // 6: apocryph.proto.v0.pod.Resource (*Key)(nil), // 7: apocryph.proto.v0.pod.Key - nil, // 8: apocryph.proto.v0.pod.Container.EnvEntry - (*Container_Image)(nil), // 9: apocryph.proto.v0.pod.Container.Image - (*Container_Port)(nil), // 10: apocryph.proto.v0.pod.Container.Port - (*Container_VolumeMount)(nil), // 11: apocryph.proto.v0.pod.Container.VolumeMount - (*Volume_FilesystemConfig)(nil), // 12: apocryph.proto.v0.pod.Volume.FilesystemConfig - (*Volume_SecretConfig)(nil), // 13: apocryph.proto.v0.pod.Volume.SecretConfig + (*KeyPair)(nil), // 8: apocryph.proto.v0.pod.KeyPair + nil, // 9: apocryph.proto.v0.pod.Container.EnvEntry + (*Container_Image)(nil), // 10: apocryph.proto.v0.pod.Container.Image + (*Container_Port)(nil), // 11: apocryph.proto.v0.pod.Container.Port + (*Container_VolumeMount)(nil), // 12: apocryph.proto.v0.pod.Container.VolumeMount + (*Volume_FilesystemConfig)(nil), // 13: apocryph.proto.v0.pod.Volume.FilesystemConfig + (*Volume_SecretConfig)(nil), // 14: apocryph.proto.v0.pod.Volume.SecretConfig } var file_pod_proto_depIdxs = []int32{ 3, // 0: apocryph.proto.v0.pod.Pod.containers:type_name -> apocryph.proto.v0.pod.Container 4, // 1: apocryph.proto.v0.pod.Pod.volumes:type_name -> apocryph.proto.v0.pod.Volume 5, // 2: apocryph.proto.v0.pod.Pod.replicas:type_name -> apocryph.proto.v0.pod.Replicas - 9, // 3: apocryph.proto.v0.pod.Container.image:type_name -> apocryph.proto.v0.pod.Container.Image - 10, // 4: apocryph.proto.v0.pod.Container.ports:type_name -> apocryph.proto.v0.pod.Container.Port - 8, // 5: apocryph.proto.v0.pod.Container.env:type_name -> apocryph.proto.v0.pod.Container.EnvEntry - 11, // 6: apocryph.proto.v0.pod.Container.volumes:type_name -> apocryph.proto.v0.pod.Container.VolumeMount - 6, // 7: apocryph.proto.v0.pod.Container.resourceRequests:type_name -> apocryph.proto.v0.pod.Resource - 0, // 8: apocryph.proto.v0.pod.Volume.type:type_name -> apocryph.proto.v0.pod.Volume.Type - 1, // 9: apocryph.proto.v0.pod.Volume.accessMode:type_name -> apocryph.proto.v0.pod.Volume.AccessMode - 12, // 10: apocryph.proto.v0.pod.Volume.filesystem:type_name -> apocryph.proto.v0.pod.Volume.FilesystemConfig - 13, // 11: apocryph.proto.v0.pod.Volume.secret:type_name -> apocryph.proto.v0.pod.Volume.SecretConfig - 7, // 12: apocryph.proto.v0.pod.Container.Image.key:type_name -> apocryph.proto.v0.pod.Key - 6, // 13: apocryph.proto.v0.pod.Volume.FilesystemConfig.resourceRequests:type_name -> apocryph.proto.v0.pod.Resource - 7, // 14: apocryph.proto.v0.pod.Volume.SecretConfig.key:type_name -> apocryph.proto.v0.pod.Key - 15, // [15:15] is the sub-list for method output_type - 15, // [15:15] is the sub-list for method input_type - 15, // [15:15] is the sub-list for extension type_name - 15, // [15:15] is the sub-list for extension extendee - 0, // [0:15] is the sub-list for field type_name + 8, // 3: apocryph.proto.v0.pod.Pod.keyPair:type_name -> apocryph.proto.v0.pod.KeyPair + 10, // 4: apocryph.proto.v0.pod.Container.image:type_name -> apocryph.proto.v0.pod.Container.Image + 11, // 5: apocryph.proto.v0.pod.Container.ports:type_name -> apocryph.proto.v0.pod.Container.Port + 9, // 6: apocryph.proto.v0.pod.Container.env:type_name -> apocryph.proto.v0.pod.Container.EnvEntry + 12, // 7: apocryph.proto.v0.pod.Container.volumes:type_name -> apocryph.proto.v0.pod.Container.VolumeMount + 6, // 8: apocryph.proto.v0.pod.Container.resourceRequests:type_name -> apocryph.proto.v0.pod.Resource + 0, // 9: apocryph.proto.v0.pod.Volume.type:type_name -> apocryph.proto.v0.pod.Volume.Type + 1, // 10: apocryph.proto.v0.pod.Volume.accessMode:type_name -> apocryph.proto.v0.pod.Volume.AccessMode + 13, // 11: apocryph.proto.v0.pod.Volume.filesystem:type_name -> apocryph.proto.v0.pod.Volume.FilesystemConfig + 14, // 12: apocryph.proto.v0.pod.Volume.secret:type_name -> apocryph.proto.v0.pod.Volume.SecretConfig + 7, // 13: apocryph.proto.v0.pod.KeyPair.key:type_name -> apocryph.proto.v0.pod.Key + 7, // 14: apocryph.proto.v0.pod.Container.Image.key:type_name -> apocryph.proto.v0.pod.Key + 6, // 15: apocryph.proto.v0.pod.Volume.FilesystemConfig.resourceRequests:type_name -> apocryph.proto.v0.pod.Resource + 7, // 16: apocryph.proto.v0.pod.Volume.SecretConfig.key:type_name -> apocryph.proto.v0.pod.Key + 17, // [17:17] is the sub-list for method output_type + 17, // [17:17] is the sub-list for method input_type + 17, // [17:17] is the sub-list for extension type_name + 17, // [17:17] is the sub-list for extension extendee + 0, // [0:17] is the sub-list for field type_name } func init() { file_pod_proto_init() } @@ -1234,8 +1309,8 @@ func file_pod_proto_init() { return nil } } - file_pod_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Container_Image); i { + file_pod_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*KeyPair); i { case 0: return &v.state case 1: @@ -1247,7 +1322,7 @@ func file_pod_proto_init() { } } file_pod_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Container_Port); i { + switch v := v.(*Container_Image); i { case 0: return &v.state case 1: @@ -1259,7 +1334,7 @@ func file_pod_proto_init() { } } file_pod_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Container_VolumeMount); i { + switch v := v.(*Container_Port); i { case 0: return &v.state case 1: @@ -1271,7 +1346,7 @@ func file_pod_proto_init() { } } file_pod_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Volume_FilesystemConfig); i { + switch v := v.(*Container_VolumeMount); i { case 0: return &v.state case 1: @@ -1283,6 +1358,18 @@ func file_pod_proto_init() { } } file_pod_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Volume_FilesystemConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pod_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Volume_SecretConfig); i { case 0: return &v.state @@ -1303,7 +1390,7 @@ func file_pod_proto_init() { (*Resource_Amount)(nil), (*Resource_AmountMillis)(nil), } - file_pod_proto_msgTypes[8].OneofWrappers = []interface{}{ + file_pod_proto_msgTypes[9].OneofWrappers = []interface{}{ (*Container_Port_HostHttpHost)(nil), (*Container_Port_HostTcpPort)(nil), } @@ -1313,7 +1400,7 @@ func file_pod_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_pod_proto_rawDesc, NumEnums: 2, - NumMessages: 12, + NumMessages: 13, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/proto/provision-pod.pb.go b/pkg/proto/provision-pod.pb.go index 48576cc8..10ecaab5 100644 --- a/pkg/proto/provision-pod.pb.go +++ b/pkg/proto/provision-pod.pb.go @@ -364,10 +364,9 @@ type ProvisionPodResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Error string `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` - Addresses []*ProvisionPodResponse_ExposedHostPort `protobuf:"bytes,2,rep,name=addresses,proto3" json:"addresses,omitempty"` - Namespace string `protobuf:"bytes,3,opt,name=namespace,proto3" json:"namespace,omitempty"` - PubAddress string `protobuf:"bytes,4,opt,name=pubAddress,proto3" json:"pubAddress,omitempty"` + Error string `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` + Addresses []*ProvisionPodResponse_ExposedHostPort `protobuf:"bytes,2,rep,name=addresses,proto3" json:"addresses,omitempty"` + Namespace string `protobuf:"bytes,3,opt,name=namespace,proto3" json:"namespace,omitempty"` } func (x *ProvisionPodResponse) Reset() { @@ -423,13 +422,6 @@ func (x *ProvisionPodResponse) GetNamespace() string { return "" } -func (x *ProvisionPodResponse) GetPubAddress() string { - if x != nil { - return x.PubAddress - } - return "" -} - type PodLogRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -530,9 +522,7 @@ type LogEntry struct { unknownFields protoimpl.UnknownFields NanosecondsUnixEpoch uint64 `protobuf:"varint,1,opt,name=NanosecondsUnixEpoch,proto3" json:"NanosecondsUnixEpoch,omitempty"` - Log string `protobuf:"bytes,2,opt,name=log,proto3" json:"log,omitempty"` - Stream string `protobuf:"bytes,3,opt,name=stream,proto3" json:"stream,omitempty"` // std(in/out/err) - Time string `protobuf:"bytes,4,opt,name=time,proto3" json:"time,omitempty"` + Line string `protobuf:"bytes,2,opt,name=line,proto3" json:"line,omitempty"` } func (x *LogEntry) Reset() { @@ -574,23 +564,9 @@ func (x *LogEntry) GetNanosecondsUnixEpoch() uint64 { return 0 } -func (x *LogEntry) GetLog() string { - if x != nil { - return x.Log - } - return "" -} - -func (x *LogEntry) GetStream() string { +func (x *LogEntry) GetLine() string { if x != nil { - return x.Stream - } - return "" -} - -func (x *LogEntry) GetTime() string { - if x != nil { - return x.Time + return x.Line } return "" } @@ -704,7 +680,7 @@ var file_provision_pod_proto_rawDesc = []byte{ 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x6f, 0x64, 0x49, - 0x44, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x70, 0x6f, 0x64, 0x49, 0x44, 0x22, 0xcb, + 0x44, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x70, 0x6f, 0x64, 0x49, 0x44, 0x22, 0xab, 0x02, 0x0a, 0x14, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x62, 0x0a, @@ -715,9 +691,7 @@ var file_provision_pod_proto_rawDesc = []byte{ 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x48, 0x6f, 0x73, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, - 0x1e, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x75, 0x62, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x1a, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x1a, 0x7b, 0x0a, 0x0f, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x48, 0x6f, 0x73, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x61, 0x64, 0x64, 0x72, @@ -734,49 +708,46 @@ var file_provision_pod_proto_rawDesc = []byte{ 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x2e, 0x4c, 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x52, 0x08, 0x6c, 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x22, 0x7c, 0x0a, 0x08, 0x4c, + 0x79, 0x52, 0x08, 0x6c, 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x22, 0x52, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x32, 0x0a, 0x14, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x55, 0x6e, 0x69, 0x78, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x14, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, - 0x64, 0x73, 0x55, 0x6e, 0x69, 0x78, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x6c, - 0x6f, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6c, 0x6f, 0x67, 0x12, 0x16, 0x0a, - 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x32, 0xe6, 0x03, 0x0a, 0x13, 0x50, 0x72, - 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x12, 0x79, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, - 0x64, 0x12, 0x33, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, + 0x64, 0x73, 0x55, 0x6e, 0x69, 0x78, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x6c, + 0x69, 0x6e, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x32, + 0xe6, 0x03, 0x0a, 0x13, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x79, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x76, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x12, 0x33, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, + 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x61, + 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, + 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x2e, 0x50, 0x72, + 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x73, 0x0a, 0x09, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x64, 0x12, + 0x30, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, + 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x34, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x70, 0x0a, 0x09, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x50, 0x6f, 0x64, 0x12, 0x30, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x64, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, - 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, - 0x6e, 0x50, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x73, 0x0a, 0x09, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x64, 0x12, 0x30, 0x2e, 0x61, 0x70, 0x6f, 0x63, - 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x50, 0x6f, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x61, 0x70, - 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, - 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x2e, 0x50, 0x72, 0x6f, - 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x70, 0x0a, 0x09, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x64, 0x12, 0x30, - 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, - 0x76, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x2e, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x31, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, - 0x64, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x6d, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x64, 0x4c, 0x6f, 0x67, - 0x73, 0x12, 0x2d, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, - 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x2e, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, - 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x30, 0x01, 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x63, 0x6f, 0x6d, 0x72, 0x61, 0x64, 0x65, 0x2d, 0x63, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, - 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, + 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6d, 0x0a, 0x0a, 0x47, 0x65, 0x74, + 0x50, 0x6f, 0x64, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x2d, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, + 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x4c, 0x6f, 0x67, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, + 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x4c, 0x6f, 0x67, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6d, 0x72, 0x61, 0x64, 0x65, 0x2d, 0x63, + 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2f, 0x70, 0x6b, 0x67, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/pkg/provider/server.go b/pkg/provider/server.go index a596fc23..92a34fae 100644 --- a/pkg/provider/server.go +++ b/pkg/provider/server.go @@ -135,7 +135,6 @@ func (s *provisionPodServer) ProvisionPod(ctx context.Context, request *connect. if err != nil { return transformError(err) } - fmt.Printf("Authorized:%v\n", request.Msg.Pod.Authorized) response := &pb.ProvisionPodResponse{} ns := tpk8s.NewTrustedPodsNamespace(namespace, request.Msg.Payment) diff --git a/pkg/publisher/deployment.go b/pkg/publisher/deployment.go index 19695c92..aa9c9ad1 100644 --- a/pkg/publisher/deployment.go +++ b/pkg/publisher/deployment.go @@ -125,80 +125,87 @@ func SaveDeployment(deploymentFile string, deploymentFormat string, deployment * } func AuthorizeAndFundApplication(ctx context.Context, response *pb.ProvisionPodResponse, deployment *pb.Deployment, ethClient *ethclient.Client, publisherAuth *bind.TransactOpts, publisherKey string, amount int64) error { - if response.PubAddress != "" { + if deployment.KeyPair != nil { // authorize the public address to control the payment channel // get a payment contract instance + pubAddress := common.HexToAddress(deployment.KeyPair.PubAddress) payment, err := abi.NewPayment(common.Address(deployment.Payment.PaymentContractAddress), ethClient) if err != nil { return fmt.Errorf("Failed instantiating payment contract: %w", err) } - _, err = payment.Authorize(publisherAuth, common.HexToAddress(response.PubAddress), common.Address(deployment.Provider.EthereumAddress), [32]byte(deployment.Payment.PodID)) + _, err = payment.Authorize(publisherAuth, pubAddress, common.Address(deployment.Provider.EthereumAddress), [32]byte(deployment.Payment.PodID)) if err != nil { return fmt.Errorf("Failed Authorizing Address: %w", err) } - fmt.Fprintf(os.Stdout, "Authorized Address Successfully %v\n", response.PubAddress) - // NOTE: the deployed application must be funded with the base // currency (eth) in order for it to be able to make transactions // (like creating subchannels) - pubAddress := common.HexToAddress(response.PubAddress) amount := big.NewInt(amount) - - // Estimate gas limit - gasLimit, err := ethClient.EstimateGas(context.Background(), ethereum.CallMsg{ - From: publisherAuth.From, - To: &pubAddress, - Value: amount, - }) + err = FundAddress(ctx, publisherKey, publisherAuth.From, pubAddress, ethClient, amount) if err != nil { - return fmt.Errorf("Failed to estimate gas: %w", err) + return err } + fmt.Fprintf(os.Stdout, "Authorized And funded address %v\n", pubAddress) + } + return nil +} - // Get gas price - gasPrice, err := ethClient.SuggestGasPrice(context.Background()) - if err != nil { - return fmt.Errorf("Failed to get gas price: %w", err) - } +func FundAddress(ctx context.Context, key string, from, to common.Address, ethClient *ethclient.Client, amount *big.Int) error { - nonce, err := ethClient.PendingNonceAt(ctx, publisherAuth.From) - if err != nil { - return fmt.Errorf("Failed to get gas price: %w", err) - } + // Estimate gas limit + gasLimit, err := ethClient.EstimateGas(context.Background(), ethereum.CallMsg{ + From: from, + To: &to, + Value: amount, + }) + if err != nil { + return fmt.Errorf("Failed to estimate gas: %w", err) + } - // Create a transaction - tx := types.NewTransaction( - nonce, - pubAddress, - amount, - gasLimit, - gasPrice, - nil, - ) - chainId, err := ethClient.ChainID(ctx) - if err != nil { - return fmt.Errorf("Failed to get chain ID: %w", err) - } + // Get gas price + gasPrice, err := ethClient.SuggestGasPrice(context.Background()) + if err != nil { + return fmt.Errorf("Failed to get gas price: %w", err) + } - var privateKey *ecdsa.PrivateKey - if privKey, ok := strings.CutPrefix(publisherKey, "0x"); ok && len(privKey) == PrivateKeySize*2 { - privateKey, err = crypto.HexToECDSA(privKey) - if err != nil { - return err - } - } + nonce, err := ethClient.PendingNonceAt(ctx, from) + if err != nil { + return fmt.Errorf("Failed to get gas price: %w", err) + } - // Sign the transaction - signedTx, err := types.SignTx(tx, types.NewEIP155Signer(chainId), privateKey) - if err != nil { - return fmt.Errorf("Failed to sign transaction: %w", err) - } + // Create a transaction + tx := types.NewTransaction( + nonce, + to, + amount, + gasLimit, + gasPrice, + nil, + ) + chainId, err := ethClient.ChainID(ctx) + if err != nil { + return fmt.Errorf("Failed to get chain ID: %w", err) + } - // Send the transaction - err = ethClient.SendTransaction(context.Background(), signedTx) + var privateKey *ecdsa.PrivateKey + if privKey, ok := strings.CutPrefix(key, "0x"); ok && len(privKey) == PrivateKeySize*2 { + privateKey, err = crypto.HexToECDSA(privKey) if err != nil { - return fmt.Errorf("Failed to send transaction: %w", err) + return err } } + + // Sign the transaction + signedTx, err := types.SignTx(tx, types.NewEIP155Signer(chainId), privateKey) + if err != nil { + return fmt.Errorf("Failed to sign transaction: %w", err) + } + + // Send the transaction + err = ethClient.SendTransaction(context.Background(), signedTx) + if err != nil { + return fmt.Errorf("Failed to send transaction: %w", err) + } return nil } diff --git a/proto/deployment.proto b/proto/deployment.proto index 5bbb0e2a..2b3be549 100644 --- a/proto/deployment.proto +++ b/proto/deployment.proto @@ -14,6 +14,8 @@ message Deployment { repeated UploadedImage images = 4; repeated UploadedSecret secrets = 5; provisionPod.ProvisionPodResponse deployed = 6; + pod.KeyPair keyPair = 7; + } message ProviderConfig { diff --git a/proto/pod.proto b/proto/pod.proto index c2423241..f6b6cdd9 100644 --- a/proto/pod.proto +++ b/proto/pod.proto @@ -9,7 +9,7 @@ message Pod { repeated Container containers = 1; repeated Volume volumes = 2; Replicas replicas = 3; - bool authorized = 4; + KeyPair keyPair = 4; } message Container { @@ -96,3 +96,9 @@ message Resource { message Key { bytes data = 1; } + +message KeyPair { + Key key = 1; + bytes privateKey= 2; + string pubAddress = 3; +} diff --git a/proto/provision-pod.proto b/proto/provision-pod.proto index 98abf6ff..43b407e9 100644 --- a/proto/provision-pod.proto +++ b/proto/provision-pod.proto @@ -52,7 +52,6 @@ message ProvisionPodResponse { string containerName = 2; uint64 containerPort = 3; } - string pubAddress = 4; } message PodLogRequest{ @@ -65,7 +64,5 @@ message PodLogResponse{ message LogEntry{ uint64 NanosecondsUnixEpoch = 1; - string log = 2; - string stream = 3; // std(in/out/err) - string time = 4; + string line= 2; } diff --git a/test/e2e/autoscaler/run-test.sh b/test/e2e/autoscaler/run-test.sh index 0333d0fd..119b5222 100755 --- a/test/e2e/autoscaler/run-test.sh +++ b/test/e2e/autoscaler/run-test.sh @@ -34,8 +34,10 @@ fi ./redeploy-contracts.sh +## 0.3: start clusters +./start-clusters.sh + ## 1.0 Starting the First Cluster -minikube start --insecure-registry='host.minikube.internal:5000' --container-runtime=containerd --driver=virtualbox -p c1 minikube profile c1 helmfile sync -f ../minikube || { while ! kubectl get -n keda endpoints ingress-nginx-controller -o json | jq '.subsets[].addresses[].ip' &>/dev/null; do sleep 1; done; helmfile apply -f ../minikube; } @@ -44,7 +46,6 @@ helmfile sync -f ../minikube || { while ! kubectl get -n keda endpoints ingress- ## 2.0: Starting the second Cluster -minikube start --insecure-registry='host.minikube.internal:5000' --container-runtime=containerd --driver=virtualbox -p c2 minikube profile c2 helmfile sync -f ../minikube || { while ! kubectl get -n keda endpoints ingress-nginx-controller -o json | jq '.subsets[].addresses[].ip' &>/dev/null; do sleep 1; done; helmfile apply -f ../minikube; } @@ -53,7 +54,6 @@ helmfile sync -f ../minikube || { while ! kubectl get -n keda endpoints ingress- ## 3.0: Starting the third Cluster -minikube start --insecure-registry='host.minikube.internal:5000' --container-runtime=containerd --driver=virtualbox -p c3 minikube profile c3 helmfile sync -f ../minikube || { while ! kubectl get -n keda endpoints ingress-nginx-controller -o json | jq '.subsets[].addresses[].ip' &>/dev/null; do sleep 1; done; helmfile apply -f ../minikube; } @@ -206,3 +206,7 @@ minikube profile c3 C3_INGRESS_URL=$(minikube service -n keda ingress-nginx-controller --url=true | head -n 1); echo $C3_INGRESS_URL go run ../../../cmd/trustedpods/ autoscale --url "$C1_INGRESS_URL" --providers "$C1_INGRESS_URL","$C2_INGRESS_URL","$C3_INGRESS_URL" + +## 6.1: Get Last deployed Autoscaler Logs +PUBLISHER_KEY=$(docker logs anvil | awk '/Private Keys/ {flag=1; next} flag && /^\(2\)/ {print $2; exit}') +go run ../../../cmd/trustedpods/ pod log ../common/manifest-autoscaler.yaml --ethereum-key "$PUBLISHER_KEY" diff --git a/test/e2e/autoscaler/start-clusters.sh b/test/e2e/autoscaler/start-clusters.sh new file mode 100755 index 00000000..7dda4a7c --- /dev/null +++ b/test/e2e/autoscaler/start-clusters.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +minikube start --insecure-registry='host.minikube.internal:5000' --container-runtime=containerd --driver=virtualbox -p c1 +minikube start --insecure-registry='host.minikube.internal:5000' --container-runtime=containerd --driver=virtualbox -p c2 +minikube start --insecure-registry='host.minikube.internal:5000' --container-runtime=containerd --driver=virtualbox -p c3 From 733d8662c5dcbe58e5153242252949ccea26be02 Mon Sep 17 00:00:00 2001 From: revoltez Date: Fri, 2 Aug 2024 10:25:48 +0100 Subject: [PATCH 6/8] fix: leftout old entry field --- test/integration/lifecycle/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/lifecycle/main.go b/test/integration/lifecycle/main.go index b3262873..1f1cef74 100644 --- a/test/integration/lifecycle/main.go +++ b/test/integration/lifecycle/main.go @@ -158,7 +158,7 @@ func GetPodLogs(client pbcon.ProvisionPodServiceClient, request *pb.PodLogReques } for stream.Receive() { resp := stream.Msg() - valStr := fmt.Sprintf("%s:%s", resp.LogEntry.Time, resp.LogEntry.Log) + valStr := fmt.Sprintf("%v", resp.LogEntry) log.Println(valStr) } err = stream.Err() From 4b6f4d3db8e56e079bef3288bbb76d59b61568c2 Mon Sep 17 00:00:00 2001 From: revoltez Date: Sat, 3 Aug 2024 22:22:06 +0100 Subject: [PATCH 7/8] fix: require channel to be unlocked, check funds, check if subchannel already exists --- contracts/src/Payment.sol | 7 +++++++ contracts/test/Payment.t.sol | 21 ++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/contracts/src/Payment.sol b/contracts/src/Payment.sol index 2442cb48..e1038802 100644 --- a/contracts/src/Payment.sol +++ b/contracts/src/Payment.sol @@ -205,15 +205,22 @@ contract Payment { // Ensure there is enough invested by the publisher if (channel.investedByPublisher < amount) revert InsufficientFunds(); + // Ensure channel is unlocked + if (channel.unlockedAt == 0 || block.timestamp < channel.unlockedAt) revert ChannelLocked(); + // Deduct the amount from the main channel's funds channel.investedByPublisher -= amount; // Create the subChannel for the authorized caller Channel storage subChannel = channels[msg.sender][newProvider][newPodId]; + if (subChannel.investedByPublisher != 0) revert AlreadyExists(); // authorize the main channel publisher to control the subchannel subChannel.authorized[publisher] = true; + // Ensure There are enough LeftOver funds + if (channel.investedByPublisher - channel.withdrawnByProvider < amount) revert InsufficientFunds(); + // fund the new sub channel with the deducted amount from the main channel subChannel.investedByPublisher += amount; subChannel.unlockTime = channel.unlockTime; // Inherit unlock time from main channel diff --git a/contracts/test/Payment.t.sol b/contracts/test/Payment.t.sol index 03226e6d..c3a6c656 100644 --- a/contracts/test/Payment.t.sol +++ b/contracts/test/Payment.t.sol @@ -194,6 +194,13 @@ contract PaymentTest is Test { // Test creating a sub-channel vm.startPrank(authorizedAddr); address newProvider = address(0x456); + + // test creating a subChannel from a locked main channel + vm.expectRevert(Payment.ChannelLocked.selector); + payment.createSubChannel(publisher, provider, podId, newProvider, newPodId, 200); + + payment.unlock(publisher, provider, podId); + vm.warp(block.timestamp + 1); payment.createSubChannel(publisher, provider, podId, newProvider, newPodId, 200); // Verify sub-channel creation @@ -215,6 +222,16 @@ contract PaymentTest is Test { bytes32 nonExistentPodId = keccak256("non-existent"); vm.expectRevert(Payment.DoesNotExist.selector); payment.createSubChannel(publisher, provider, nonExistentPodId, newProvider, newPodId, 100); + + // test creating a subchannel from a channel with insufficient funds + vm.expectRevert(Payment.InsufficientFunds.selector); + payment.createSubChannel(publisher, provider, podId, provider, podId, 200); + + // test creating a subchannel that already exists + vm.startPrank(publisher); + payment.authorize(publisher, provider, podId); + vm.expectRevert(Payment.AlreadyExists.selector); + payment.createSubChannel(publisher, provider, podId, provider, podId, 100); // Test creating sub-channel without authorization vm.stopPrank(); @@ -247,6 +264,8 @@ contract PaymentTest is Test { vm.startPrank(subChannelCreator); address newProvider = address(0x456); + payment.unlock(publisher, provider, podId); + vm.warp(block.timestamp + 10); payment.createSubChannel(publisher, provider, podId, newProvider, newPodId, 200); // create the subchannel vm.stopPrank(); @@ -270,7 +289,7 @@ contract PaymentTest is Test { // test closing nonexistent Channel vm.expectRevert(Payment.DoesNotExist.selector); payment.closeChannel(subChannelCreator, newProvider, newPodId); - + // Test that non-authorized address can't close channel vm.stopPrank(); vm.prank(address(0xdead)); From 288f792d0f89e2abd7f6551f0dee48738abf8d09 Mon Sep 17 00:00:00 2001 From: revoltez Date: Wed, 14 Aug 2024 10:39:54 +0100 Subject: [PATCH 8/8] chore: remove encryption key from KeyPair in proto --- cmd/trustedpods/deploy.go | 12 ++------- pkg/autoscaler/server.go | 3 +++ pkg/ethereum/client.go | 4 +-- pkg/kubernetes/pods.go | 15 +---------- pkg/proto-ts/pod_pb.ts | 12 +++------ pkg/proto/pod.pb.go | 52 +++++++++++++++------------------------ proto/pod.proto | 3 +-- 7 files changed, 32 insertions(+), 69 deletions(-) diff --git a/cmd/trustedpods/deploy.go b/cmd/trustedpods/deploy.go index 44e871cf..81eb8c11 100644 --- a/cmd/trustedpods/deploy.go +++ b/cmd/trustedpods/deploy.go @@ -10,7 +10,6 @@ import ( "path/filepath" "github.com/comrade-coop/apocryph/pkg/abi" - tpcrypto "github.com/comrade-coop/apocryph/pkg/crypto" "github.com/comrade-coop/apocryph/pkg/ethereum" "github.com/comrade-coop/apocryph/pkg/ipcr" tpipfs "github.com/comrade-coop/apocryph/pkg/ipfs" @@ -99,10 +98,6 @@ var deployPodCmd = &cobra.Command{ configureDeployment(deployment) if authorize { - encryptionKey, err := tpcrypto.NewKey(tpcrypto.KeyTypeAESGCM256) - if err != nil { - return fmt.Errorf("Could not create AES key: %v", err) - } // create the keypair that will be accessible for all pods privateKey, err := ecdsa.GenerateKey(crypto.S256(), rand.Reader) if err != nil { @@ -115,12 +110,9 @@ var deployPodCmd = &cobra.Command{ pubAddress := crypto.PubkeyToAddress(privateKey.PublicKey) - encryptedPrivateKey, err := tpcrypto.EncryptWithKey(encryptionKey, crypto.FromECDSA(privateKey)) - if err != nil { - return fmt.Errorf("Could not encrypt private key: %v", err) - } + encodedPrivateKey := ethereum.EncodePrivateKey(crypto.FromECDSA(privateKey)) - pod.KeyPair = &pb.KeyPair{Key: encryptionKey, PrivateKey: encryptedPrivateKey, PubAddress: pubAddress.Hex()} + pod.KeyPair = &pb.KeyPair{PrivateKey: encodedPrivateKey, PubAddress: pubAddress.Hex()} deployment.KeyPair = pod.KeyPair } diff --git a/pkg/autoscaler/server.go b/pkg/autoscaler/server.go index fa12020a..c9c889de 100644 --- a/pkg/autoscaler/server.go +++ b/pkg/autoscaler/server.go @@ -67,6 +67,9 @@ func NewAutoSalerServer(ethereumRpc string, p2pHost host.Host) (*AutoScalerServe log.Printf("ENV Variables: Payment_Address: %v, Publisher Address: %v, ProviderAddress: %v, podId: %v\n", paymentAddress, publisherAddress, providerAddress, podId) privateKey, err := ethereum.DecodePrivateKey(key) + if err != nil { + return nil, fmt.Errorf("Failed decoding private Key: %v", err) + } chainID, err := ethClient.ChainID(context.Background()) if err != nil { diff --git a/pkg/ethereum/client.go b/pkg/ethereum/client.go index fddde32e..eb2d35ee 100644 --- a/pkg/ethereum/client.go +++ b/pkg/ethereum/client.go @@ -126,8 +126,8 @@ func GetAccountAndSigner(accountString string, client *ethclient.Client) (*bind. } } -func EncodePrivateKey(privateKeyBytes []byte) (string, error) { - return hex.EncodeToString(privateKeyBytes), nil +func EncodePrivateKey(privateKeyBytes []byte) string { + return hex.EncodeToString(privateKeyBytes) } func DecodePrivateKey(encodedKey string) (*ecdsa.PrivateKey, error) { diff --git a/pkg/kubernetes/pods.go b/pkg/kubernetes/pods.go index e2b51584..7b39cfc7 100644 --- a/pkg/kubernetes/pods.go +++ b/pkg/kubernetes/pods.go @@ -8,8 +8,6 @@ import ( "strings" "github.com/comrade-coop/apocryph/pkg/constants" - tpcrypto "github.com/comrade-coop/apocryph/pkg/crypto" - "github.com/comrade-coop/apocryph/pkg/ethereum" pb "github.com/comrade-coop/apocryph/pkg/proto" "github.com/ethereum/go-ethereum/common" kedahttpv1alpha1 "github.com/kedacore/http-add-on/operator/apis/http/v1alpha1" @@ -116,24 +114,13 @@ func ApplyPodRequest( } if podManifest.KeyPair != nil { - privatekey, err := tpcrypto.DecryptWithKey(podManifest.KeyPair.Key, podManifest.KeyPair.PrivateKey) - if err != nil { - return fmt.Errorf("Failed Decrypting private key: %v\n", err) - } - - key, err := ethereum.EncodePrivateKey(privatekey) - if err != nil { - return fmt.Errorf("Failed encoding private key: %v\n", err) - } - - containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: constants.PRIVATE_KEY, Value: key}) // save as hex to parse later as hex containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: constants.PAYMENT_ADDR_KEY, Value: common.BytesToAddress(paymentChannel.ContractAddress).Hex()}) containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: constants.PUBLISHER_ADDR_KEY, Value: common.BytesToAddress(paymentChannel.PublisherAddress).Hex()}) containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: constants.PROVIDER_ADDR_KEY, Value: common.BytesToAddress(paymentChannel.ProviderAddress).Hex()}) containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: constants.POD_ID_KEY, Value: common.BytesToHash(paymentChannel.PodID).Hex()}) - containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: constants.PRIVATE_KEY, Value: key}) containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: constants.PUBLIC_ADDRESS_KEY, Value: podManifest.KeyPair.PubAddress}) + containerSpec.Env = append(containerSpec.Env, corev1.EnvVar{Name: constants.PRIVATE_KEY, Value: podManifest.KeyPair.PrivateKey}) } for field, value := range container.Env { diff --git a/pkg/proto-ts/pod_pb.ts b/pkg/proto-ts/pod_pb.ts index b89030fb..e840de7a 100644 --- a/pkg/proto-ts/pod_pb.ts +++ b/pkg/proto-ts/pod_pb.ts @@ -684,14 +684,9 @@ export class Key extends Message { */ export class KeyPair extends Message { /** - * @generated from field: apocryph.proto.v0.pod.Key key = 1; + * @generated from field: string privateKey = 2; */ - key?: Key; - - /** - * @generated from field: bytes privateKey = 2; - */ - privateKey = new Uint8Array(0); + privateKey = ""; /** * @generated from field: string pubAddress = 3; @@ -706,8 +701,7 @@ export class KeyPair extends Message { static readonly runtime: typeof proto3 = proto3; static readonly typeName = "apocryph.proto.v0.pod.KeyPair"; static readonly fields: FieldList = proto3.util.newFieldList(() => [ - { no: 1, name: "key", kind: "message", T: Key }, - { no: 2, name: "privateKey", kind: "scalar", T: 12 /* ScalarType.BYTES */ }, + { no: 2, name: "privateKey", kind: "scalar", T: 9 /* ScalarType.STRING */ }, { no: 3, name: "pubAddress", kind: "scalar", T: 9 /* ScalarType.STRING */ }, ]); diff --git a/pkg/proto/pod.pb.go b/pkg/proto/pod.pb.go index 32e21b7a..475a5556 100644 --- a/pkg/proto/pod.pb.go +++ b/pkg/proto/pod.pb.go @@ -609,8 +609,7 @@ type KeyPair struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Key *Key `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - PrivateKey []byte `protobuf:"bytes,2,opt,name=privateKey,proto3" json:"privateKey,omitempty"` + PrivateKey string `protobuf:"bytes,2,opt,name=privateKey,proto3" json:"privateKey,omitempty"` PubAddress string `protobuf:"bytes,3,opt,name=pubAddress,proto3" json:"pubAddress,omitempty"` } @@ -646,18 +645,11 @@ func (*KeyPair) Descriptor() ([]byte, []int) { return file_pod_proto_rawDescGZIP(), []int{6} } -func (x *KeyPair) GetKey() *Key { - if x != nil { - return x.Key - } - return nil -} - -func (x *KeyPair) GetPrivateKey() []byte { +func (x *KeyPair) GetPrivateKey() string { if x != nil { return x.PrivateKey } - return nil + return "" } func (x *KeyPair) GetPubAddress() string { @@ -1161,18 +1153,15 @@ var file_pod_proto_rawDesc = []byte{ 0x52, 0x0c, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x42, 0x0a, 0x0a, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x19, 0x0a, 0x03, 0x4b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x77, 0x0a, 0x07, 0x4b, 0x65, 0x79, 0x50, 0x61, 0x69, 0x72, - 0x12, 0x2c, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, - 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, - 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x1e, - 0x0a, 0x0a, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1e, - 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x70, 0x75, 0x62, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x2c, - 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6d, - 0x72, 0x61, 0x64, 0x65, 0x2d, 0x63, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x6f, 0x63, 0x72, 0x79, - 0x70, 0x68, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x49, 0x0a, 0x07, 0x4b, 0x65, 0x79, 0x50, 0x61, 0x69, 0x72, + 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, + 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x75, 0x62, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, + 0x6f, 0x6d, 0x72, 0x61, 0x64, 0x65, 0x2d, 0x63, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x6f, 0x63, + 0x72, 0x79, 0x70, 0x68, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1220,15 +1209,14 @@ var file_pod_proto_depIdxs = []int32{ 1, // 10: apocryph.proto.v0.pod.Volume.accessMode:type_name -> apocryph.proto.v0.pod.Volume.AccessMode 13, // 11: apocryph.proto.v0.pod.Volume.filesystem:type_name -> apocryph.proto.v0.pod.Volume.FilesystemConfig 14, // 12: apocryph.proto.v0.pod.Volume.secret:type_name -> apocryph.proto.v0.pod.Volume.SecretConfig - 7, // 13: apocryph.proto.v0.pod.KeyPair.key:type_name -> apocryph.proto.v0.pod.Key - 7, // 14: apocryph.proto.v0.pod.Container.Image.key:type_name -> apocryph.proto.v0.pod.Key - 6, // 15: apocryph.proto.v0.pod.Volume.FilesystemConfig.resourceRequests:type_name -> apocryph.proto.v0.pod.Resource - 7, // 16: apocryph.proto.v0.pod.Volume.SecretConfig.key:type_name -> apocryph.proto.v0.pod.Key - 17, // [17:17] is the sub-list for method output_type - 17, // [17:17] is the sub-list for method input_type - 17, // [17:17] is the sub-list for extension type_name - 17, // [17:17] is the sub-list for extension extendee - 0, // [0:17] is the sub-list for field type_name + 7, // 13: apocryph.proto.v0.pod.Container.Image.key:type_name -> apocryph.proto.v0.pod.Key + 6, // 14: apocryph.proto.v0.pod.Volume.FilesystemConfig.resourceRequests:type_name -> apocryph.proto.v0.pod.Resource + 7, // 15: apocryph.proto.v0.pod.Volume.SecretConfig.key:type_name -> apocryph.proto.v0.pod.Key + 16, // [16:16] is the sub-list for method output_type + 16, // [16:16] is the sub-list for method input_type + 16, // [16:16] is the sub-list for extension type_name + 16, // [16:16] is the sub-list for extension extendee + 0, // [0:16] is the sub-list for field type_name } func init() { file_pod_proto_init() } diff --git a/proto/pod.proto b/proto/pod.proto index f6b6cdd9..9291f981 100644 --- a/proto/pod.proto +++ b/proto/pod.proto @@ -98,7 +98,6 @@ message Key { } message KeyPair { - Key key = 1; - bytes privateKey= 2; + string privateKey= 2; string pubAddress = 3; }