From 999eb6c6248df160e68f34c9881442474f57fdc2 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Thu, 19 Jan 2023 11:46:26 +0200 Subject: [PATCH 001/164] Import migrations protos from wasmd --- proto/secret/compute/v1beta1/msg.proto | 47 ++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/proto/secret/compute/v1beta1/msg.proto b/proto/secret/compute/v1beta1/msg.proto index a91c6696b..8f357b286 100644 --- a/proto/secret/compute/v1beta1/msg.proto +++ b/proto/secret/compute/v1beta1/msg.proto @@ -43,10 +43,13 @@ message MsgInstantiateContract { string callback_code_hash = 2; uint64 code_id = 3 [(gogoproto.customname) = "CodeID"]; string label = 4; + // init_msg is an encrypted input to pass to the contract on init bytes init_msg = 5; repeated cosmos.base.v1beta1.Coin init_funds = 6 [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; // used internally for encryption, should always be empty in a signed transaction bytes callback_sig = 7 [(gogoproto.customname) = "CallbackSig"]; + // Admin is an optional address that can execute migrations + string admin = 8; } // MsgInstantiateContractResponse return instantiation result data @@ -64,6 +67,7 @@ message MsgExecuteContract { bytes sender = 1 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"]; // contract is the canonical address of the contract bytes contract = 2 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"]; + // msg is an encrypted input to pass to the contract on execute bytes msg = 3; string callback_code_hash = 4; repeated cosmos.base.v1beta1.Coin sent_funds = 5 [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; @@ -76,3 +80,46 @@ message MsgExecuteContractResponse { // Data contains base64-encoded bytes to returned from the contract bytes data = 1; } + +// MsgMigrateContract runs a code upgrade/ downgrade for a smart contract +message MsgMigrateContract { + // Sender is the that actor that signed the messages + string sender = 1; + // Contract is the address of the smart contract + string contract = 2; + // CodeID references the new WASM code + uint64 code_id = 3 [ (gogoproto.customname) = "CodeID" ]; + // msg is an encrypted input to pass to the contract on migration + bytes msg = 4; +} + +// MsgMigrateContractResponse returns contract migration result data. +message MsgMigrateContractResponse { + // Data contains same raw bytes returned as data from the wasm contract. + // (May be empty) + bytes data = 1; +} + +// MsgUpdateAdmin sets a new admin for a smart contract +message MsgUpdateAdmin { + // Sender is the that actor that signed the messages + string sender = 1; + // NewAdmin address to be set + string new_admin = 2; + // Contract is the address of the smart contract + string contract = 3; +} + +// MsgUpdateAdminResponse returns empty data +message MsgUpdateAdminResponse {} + +// MsgClearAdmin removes any admin stored for a smart contract +message MsgClearAdmin { + // Sender is the that actor that signed the messages + string sender = 1; + // Contract is the address of the smart contract + string contract = 3; +} + +// MsgClearAdminResponse returns empty data +message MsgClearAdminResponse {} \ No newline at end of file From d52cc7a74ff306dfa46fd184675c69376ca23f57 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Mon, 6 Feb 2023 21:04:34 +0200 Subject: [PATCH 002/164] Store admin on init --- proto/secret/compute/v1beta1/msg.proto | 2 +- proto/secret/compute/v1beta1/types.proto | 8 +- x/compute/handler.go | 2 +- x/compute/internal/keeper/keeper.go | 6 +- x/compute/internal/keeper/msg_server.go | 2 +- x/compute/internal/types/msg.pb.go | 1872 ++++++++++++++++++---- x/compute/internal/types/types.go | 3 +- x/compute/internal/types/types.pb.go | 157 +- 8 files changed, 1698 insertions(+), 354 deletions(-) diff --git a/proto/secret/compute/v1beta1/msg.proto b/proto/secret/compute/v1beta1/msg.proto index 8f357b286..cb8dd08fe 100644 --- a/proto/secret/compute/v1beta1/msg.proto +++ b/proto/secret/compute/v1beta1/msg.proto @@ -49,7 +49,7 @@ message MsgInstantiateContract { // used internally for encryption, should always be empty in a signed transaction bytes callback_sig = 7 [(gogoproto.customname) = "CallbackSig"]; // Admin is an optional address that can execute migrations - string admin = 8; + bytes admin = 8 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"]; } // MsgInstantiateContractResponse return instantiation result data diff --git a/proto/secret/compute/v1beta1/types.proto b/proto/secret/compute/v1beta1/types.proto index 445fccaca..c5c9400a0 100644 --- a/proto/secret/compute/v1beta1/types.proto +++ b/proto/secret/compute/v1beta1/types.proto @@ -36,13 +36,17 @@ message ContractCustomInfo { // ContractInfo stores a WASM contract instance message ContractInfo { + // CodeID is the reference to the stored Wasm code uint64 code_id = 1 [(gogoproto.customname) = "CodeID"]; + // Creator address who initially instantiated the contract bytes creator = 2 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"]; + // Label is mandatory metadata to be stored with a contract instance. string label = 4; - // never show this in query results, just use for sorting - // (Note: when using json tag "-" amino refused to serialize it...) + // Created Tx position when the contract was instantiated. AbsoluteTxPosition created = 5; string ibc_port_id = 6 [ (gogoproto.customname) = "IBCPortID" ]; + // Admin is an optional address that can execute migrations + bytes admin = 7 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"]; } // AbsoluteTxPosition can be used to sort contracts diff --git a/x/compute/handler.go b/x/compute/handler.go index fd83f7714..325da1d40 100644 --- a/x/compute/handler.go +++ b/x/compute/handler.go @@ -73,7 +73,7 @@ func handleStoreCode(ctx sdk.Context, k Keeper, msg *MsgStoreCode) (*sdk.Result, } func handleInstantiate(ctx sdk.Context, k Keeper, msg *MsgInstantiateContract) (*sdk.Result, error) { - contractAddr, data, err := k.Instantiate(ctx, msg.CodeID, msg.Sender, msg.InitMsg, msg.Label, msg.InitFunds, msg.CallbackSig) + contractAddr, data, err := k.Instantiate(ctx, msg.CodeID, msg.Sender, msg.Admin, msg.InitMsg, msg.Label, msg.InitFunds, msg.CallbackSig) if err != nil { result := sdk.Result{} result.Data = data diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index f36c6a727..99e4b4825 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -314,7 +314,7 @@ func V010MsgsToV1SubMsgs(contractAddr string, msgs []v010wasmTypes.CosmosMsg) ([ } // Instantiate creates an instance of a WASM contract -func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator sdk.AccAddress, initMsg []byte, label string, deposit sdk.Coins, callbackSig []byte) (sdk.AccAddress, []byte, error) { +func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator sdk.AccAddress, admin sdk.AccAddress, initMsg []byte, label string, deposit sdk.Coins, callbackSig []byte) (sdk.AccAddress, []byte, error) { defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "instantiate") ctx.GasMeter().ConsumeGas(types.InstanceCost, "Loading CosmWasm module: init") @@ -415,7 +415,7 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator sdk.AccAddre // persist instance createdAt := types.NewAbsoluteTxPosition(ctx) - contractInfo := types.NewContractInfo(codeID, creator, label, createdAt) + contractInfo := types.NewContractInfo(codeID, creator, admin, label, createdAt) store.Set(types.GetContractAddressKey(contractAddress), k.cdc.MustMarshal(&contractInfo)) store.Set(types.GetContractEnclaveKey(contractAddress), key) @@ -435,7 +435,7 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator sdk.AccAddre case *v1wasmTypes.Response: // persist instance first createdAt := types.NewAbsoluteTxPosition(ctx) - contractInfo := types.NewContractInfo(codeID, creator, label, createdAt) + contractInfo := types.NewContractInfo(codeID, creator, admin, label, createdAt) // check for IBC flag report, err := k.wasmer.AnalyzeCode(codeInfo.CodeHash) diff --git a/x/compute/internal/keeper/msg_server.go b/x/compute/internal/keeper/msg_server.go index 7c6abf9e7..28dd9d998 100644 --- a/x/compute/internal/keeper/msg_server.go +++ b/x/compute/internal/keeper/msg_server.go @@ -49,7 +49,7 @@ func (m msgServer) StoreCode(goCtx context.Context, msg *types.MsgStoreCode) (*t func (m msgServer) InstantiateContract(goCtx context.Context, msg *types.MsgInstantiateContract) (*types.MsgInstantiateContractResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - contractAddr, data, err := m.keeper.Instantiate(ctx, msg.CodeID, msg.Sender, msg.InitMsg, msg.Label, msg.InitFunds, msg.CallbackSig) + contractAddr, data, err := m.keeper.Instantiate(ctx, msg.CodeID, msg.Sender, msg.Admin, msg.InitMsg, msg.Label, msg.InitFunds, msg.CallbackSig) if err != nil { return nil, err } diff --git a/x/compute/internal/types/msg.pb.go b/x/compute/internal/types/msg.pb.go index 532831cc2..39238377c 100644 --- a/x/compute/internal/types/msg.pb.go +++ b/x/compute/internal/types/msg.pb.go @@ -126,10 +126,13 @@ type MsgInstantiateContract struct { CallbackCodeHash string `protobuf:"bytes,2,opt,name=callback_code_hash,json=callbackCodeHash,proto3" json:"callback_code_hash,omitempty"` CodeID uint64 `protobuf:"varint,3,opt,name=code_id,json=codeId,proto3" json:"code_id,omitempty"` Label string `protobuf:"bytes,4,opt,name=label,proto3" json:"label,omitempty"` - InitMsg []byte `protobuf:"bytes,5,opt,name=init_msg,json=initMsg,proto3" json:"init_msg,omitempty"` - InitFunds github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,6,rep,name=init_funds,json=initFunds,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"init_funds"` + // init_msg is an encrypted input to pass to the contract on init + InitMsg []byte `protobuf:"bytes,5,opt,name=init_msg,json=initMsg,proto3" json:"init_msg,omitempty"` + InitFunds github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,6,rep,name=init_funds,json=initFunds,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"init_funds"` // used internally for encryption, should always be empty in a signed transaction CallbackSig []byte `protobuf:"bytes,7,opt,name=callback_sig,json=callbackSig,proto3" json:"callback_sig,omitempty"` + // Admin is an optional address that can execute migrations + Admin github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,8,opt,name=admin,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"admin,omitempty"` } func (m *MsgInstantiateContract) Reset() { *m = MsgInstantiateContract{} } @@ -224,10 +227,11 @@ type MsgExecuteContract struct { // sender is the canonical address of the sender Sender github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,1,opt,name=sender,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"sender,omitempty"` // contract is the canonical address of the contract - Contract github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,2,opt,name=contract,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"contract,omitempty"` - Msg []byte `protobuf:"bytes,3,opt,name=msg,proto3" json:"msg,omitempty"` - CallbackCodeHash string `protobuf:"bytes,4,opt,name=callback_code_hash,json=callbackCodeHash,proto3" json:"callback_code_hash,omitempty"` - SentFunds github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,5,rep,name=sent_funds,json=sentFunds,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"sent_funds"` + Contract github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,2,opt,name=contract,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"contract,omitempty"` + // msg is an encrypted input to pass to the contract on execute + Msg []byte `protobuf:"bytes,3,opt,name=msg,proto3" json:"msg,omitempty"` + CallbackCodeHash string `protobuf:"bytes,4,opt,name=callback_code_hash,json=callbackCodeHash,proto3" json:"callback_code_hash,omitempty"` + SentFunds github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,5,rep,name=sent_funds,json=sentFunds,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"sent_funds"` // used internally for encryption, should always be empty in a signed transaction CallbackSig []byte `protobuf:"bytes,6,opt,name=callback_sig,json=callbackSig,proto3" json:"callback_sig,omitempty"` } @@ -311,6 +315,319 @@ func (m *MsgExecuteContractResponse) GetData() []byte { return nil } +// MsgMigrateContract runs a code upgrade/ downgrade for a smart contract +type MsgMigrateContract struct { + // Sender is the that actor that signed the messages + Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"` + // Contract is the address of the smart contract + Contract string `protobuf:"bytes,2,opt,name=contract,proto3" json:"contract,omitempty"` + // CodeID references the new WASM code + CodeID uint64 `protobuf:"varint,3,opt,name=code_id,json=codeId,proto3" json:"code_id,omitempty"` + // msg is an encrypted input to pass to the contract on migration + Msg []byte `protobuf:"bytes,4,opt,name=msg,proto3" json:"msg,omitempty"` +} + +func (m *MsgMigrateContract) Reset() { *m = MsgMigrateContract{} } +func (m *MsgMigrateContract) String() string { return proto.CompactTextString(m) } +func (*MsgMigrateContract) ProtoMessage() {} +func (*MsgMigrateContract) Descriptor() ([]byte, []int) { + return fileDescriptor_6815433faf72a133, []int{6} +} +func (m *MsgMigrateContract) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgMigrateContract) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgMigrateContract.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgMigrateContract) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgMigrateContract.Merge(m, src) +} +func (m *MsgMigrateContract) XXX_Size() int { + return m.Size() +} +func (m *MsgMigrateContract) XXX_DiscardUnknown() { + xxx_messageInfo_MsgMigrateContract.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgMigrateContract proto.InternalMessageInfo + +func (m *MsgMigrateContract) GetSender() string { + if m != nil { + return m.Sender + } + return "" +} + +func (m *MsgMigrateContract) GetContract() string { + if m != nil { + return m.Contract + } + return "" +} + +func (m *MsgMigrateContract) GetCodeID() uint64 { + if m != nil { + return m.CodeID + } + return 0 +} + +func (m *MsgMigrateContract) GetMsg() []byte { + if m != nil { + return m.Msg + } + return nil +} + +// MsgMigrateContractResponse returns contract migration result data. +type MsgMigrateContractResponse struct { + // Data contains same raw bytes returned as data from the wasm contract. + // (May be empty) + Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` +} + +func (m *MsgMigrateContractResponse) Reset() { *m = MsgMigrateContractResponse{} } +func (m *MsgMigrateContractResponse) String() string { return proto.CompactTextString(m) } +func (*MsgMigrateContractResponse) ProtoMessage() {} +func (*MsgMigrateContractResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_6815433faf72a133, []int{7} +} +func (m *MsgMigrateContractResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgMigrateContractResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgMigrateContractResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgMigrateContractResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgMigrateContractResponse.Merge(m, src) +} +func (m *MsgMigrateContractResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgMigrateContractResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgMigrateContractResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgMigrateContractResponse proto.InternalMessageInfo + +func (m *MsgMigrateContractResponse) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +// MsgUpdateAdmin sets a new admin for a smart contract +type MsgUpdateAdmin struct { + // Sender is the that actor that signed the messages + Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"` + // NewAdmin address to be set + NewAdmin string `protobuf:"bytes,2,opt,name=new_admin,json=newAdmin,proto3" json:"new_admin,omitempty"` + // Contract is the address of the smart contract + Contract string `protobuf:"bytes,3,opt,name=contract,proto3" json:"contract,omitempty"` +} + +func (m *MsgUpdateAdmin) Reset() { *m = MsgUpdateAdmin{} } +func (m *MsgUpdateAdmin) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateAdmin) ProtoMessage() {} +func (*MsgUpdateAdmin) Descriptor() ([]byte, []int) { + return fileDescriptor_6815433faf72a133, []int{8} +} +func (m *MsgUpdateAdmin) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateAdmin) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateAdmin.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgUpdateAdmin) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateAdmin.Merge(m, src) +} +func (m *MsgUpdateAdmin) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateAdmin) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateAdmin.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateAdmin proto.InternalMessageInfo + +func (m *MsgUpdateAdmin) GetSender() string { + if m != nil { + return m.Sender + } + return "" +} + +func (m *MsgUpdateAdmin) GetNewAdmin() string { + if m != nil { + return m.NewAdmin + } + return "" +} + +func (m *MsgUpdateAdmin) GetContract() string { + if m != nil { + return m.Contract + } + return "" +} + +// MsgUpdateAdminResponse returns empty data +type MsgUpdateAdminResponse struct { +} + +func (m *MsgUpdateAdminResponse) Reset() { *m = MsgUpdateAdminResponse{} } +func (m *MsgUpdateAdminResponse) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateAdminResponse) ProtoMessage() {} +func (*MsgUpdateAdminResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_6815433faf72a133, []int{9} +} +func (m *MsgUpdateAdminResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateAdminResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateAdminResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgUpdateAdminResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateAdminResponse.Merge(m, src) +} +func (m *MsgUpdateAdminResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateAdminResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateAdminResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateAdminResponse proto.InternalMessageInfo + +// MsgClearAdmin removes any admin stored for a smart contract +type MsgClearAdmin struct { + // Sender is the that actor that signed the messages + Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"` + // Contract is the address of the smart contract + Contract string `protobuf:"bytes,3,opt,name=contract,proto3" json:"contract,omitempty"` +} + +func (m *MsgClearAdmin) Reset() { *m = MsgClearAdmin{} } +func (m *MsgClearAdmin) String() string { return proto.CompactTextString(m) } +func (*MsgClearAdmin) ProtoMessage() {} +func (*MsgClearAdmin) Descriptor() ([]byte, []int) { + return fileDescriptor_6815433faf72a133, []int{10} +} +func (m *MsgClearAdmin) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgClearAdmin) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgClearAdmin.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgClearAdmin) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgClearAdmin.Merge(m, src) +} +func (m *MsgClearAdmin) XXX_Size() int { + return m.Size() +} +func (m *MsgClearAdmin) XXX_DiscardUnknown() { + xxx_messageInfo_MsgClearAdmin.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgClearAdmin proto.InternalMessageInfo + +func (m *MsgClearAdmin) GetSender() string { + if m != nil { + return m.Sender + } + return "" +} + +func (m *MsgClearAdmin) GetContract() string { + if m != nil { + return m.Contract + } + return "" +} + +// MsgClearAdminResponse returns empty data +type MsgClearAdminResponse struct { +} + +func (m *MsgClearAdminResponse) Reset() { *m = MsgClearAdminResponse{} } +func (m *MsgClearAdminResponse) String() string { return proto.CompactTextString(m) } +func (*MsgClearAdminResponse) ProtoMessage() {} +func (*MsgClearAdminResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_6815433faf72a133, []int{11} +} +func (m *MsgClearAdminResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgClearAdminResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgClearAdminResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgClearAdminResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgClearAdminResponse.Merge(m, src) +} +func (m *MsgClearAdminResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgClearAdminResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgClearAdminResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgClearAdminResponse proto.InternalMessageInfo + func init() { proto.RegisterType((*MsgStoreCode)(nil), "secret.compute.v1beta1.MsgStoreCode") proto.RegisterType((*MsgStoreCodeResponse)(nil), "secret.compute.v1beta1.MsgStoreCodeResponse") @@ -318,56 +635,70 @@ func init() { proto.RegisterType((*MsgInstantiateContractResponse)(nil), "secret.compute.v1beta1.MsgInstantiateContractResponse") proto.RegisterType((*MsgExecuteContract)(nil), "secret.compute.v1beta1.MsgExecuteContract") proto.RegisterType((*MsgExecuteContractResponse)(nil), "secret.compute.v1beta1.MsgExecuteContractResponse") + proto.RegisterType((*MsgMigrateContract)(nil), "secret.compute.v1beta1.MsgMigrateContract") + proto.RegisterType((*MsgMigrateContractResponse)(nil), "secret.compute.v1beta1.MsgMigrateContractResponse") + proto.RegisterType((*MsgUpdateAdmin)(nil), "secret.compute.v1beta1.MsgUpdateAdmin") + proto.RegisterType((*MsgUpdateAdminResponse)(nil), "secret.compute.v1beta1.MsgUpdateAdminResponse") + proto.RegisterType((*MsgClearAdmin)(nil), "secret.compute.v1beta1.MsgClearAdmin") + proto.RegisterType((*MsgClearAdminResponse)(nil), "secret.compute.v1beta1.MsgClearAdminResponse") } func init() { proto.RegisterFile("secret/compute/v1beta1/msg.proto", fileDescriptor_6815433faf72a133) } var fileDescriptor_6815433faf72a133 = []byte{ - // 697 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0x3d, 0x4f, 0x1b, 0x4b, - 0x14, 0xf5, 0xb2, 0xc6, 0xc6, 0x17, 0xeb, 0x81, 0xe6, 0x21, 0xb4, 0xb8, 0x58, 0x5b, 0x7e, 0xaf, - 0xb0, 0x9e, 0x60, 0x17, 0xfc, 0x24, 0x0a, 0x52, 0x61, 0x92, 0x28, 0x2e, 0x4c, 0xb1, 0x8e, 0x14, - 0x29, 0x8d, 0x35, 0x3b, 0x3b, 0x59, 0x2f, 0xd8, 0x3b, 0xce, 0xce, 0x38, 0x40, 0x91, 0x3e, 0x4d, - 0xa4, 0x14, 0xf9, 0x01, 0xa9, 0xf3, 0x4b, 0x48, 0x47, 0x49, 0xe5, 0x44, 0xe6, 0x5f, 0xa4, 0x8a, - 0x66, 0x76, 0xd7, 0xb6, 0x88, 0x41, 0x4e, 0x14, 0x2a, 0xcf, 0xf5, 0x3d, 0x7b, 0xee, 0xc7, 0x39, - 0x9a, 0x81, 0x0a, 0xa7, 0x24, 0xa2, 0xc2, 0x26, 0xac, 0x3f, 0x18, 0x0a, 0x6a, 0xbf, 0xd9, 0x73, - 0xa9, 0xc0, 0x7b, 0x76, 0x9f, 0xfb, 0xd6, 0x20, 0x62, 0x82, 0xa1, 0xcd, 0x18, 0x61, 0x25, 0x08, - 0x2b, 0x41, 0x94, 0x36, 0x7c, 0xe6, 0x33, 0x05, 0xb1, 0xe5, 0x29, 0x46, 0x97, 0x4c, 0xc2, 0x78, - 0x9f, 0x71, 0xdb, 0xc5, 0x7c, 0x4a, 0x46, 0x58, 0x10, 0xc6, 0xf9, 0xea, 0x17, 0x0d, 0x8a, 0x2d, - 0xee, 0xb7, 0x05, 0x8b, 0xe8, 0x11, 0xf3, 0x28, 0x6a, 0x42, 0x8e, 0xd3, 0xd0, 0xa3, 0x91, 0xa1, - 0x55, 0xb4, 0x5a, 0xb1, 0xb1, 0xf7, 0x7d, 0x54, 0xde, 0xf1, 0x03, 0xd1, 0x1d, 0xba, 0xb2, 0xa4, - 0x9d, 0xf0, 0xc5, 0x3f, 0x3b, 0xdc, 0x3b, 0xb5, 0xc5, 0xc5, 0x80, 0x72, 0xeb, 0x90, 0x90, 0x43, - 0xcf, 0x8b, 0x28, 0xe7, 0x4e, 0x42, 0x80, 0xf6, 0xe1, 0xaf, 0x33, 0xcc, 0xfb, 0x1d, 0xf7, 0x42, - 0xd0, 0x0e, 0x61, 0x1e, 0x35, 0x96, 0x14, 0xe5, 0xfa, 0x78, 0x54, 0x2e, 0xbe, 0x38, 0x6c, 0xb7, - 0x1a, 0x17, 0x42, 0x15, 0x75, 0x8a, 0x12, 0x97, 0x46, 0x68, 0x13, 0x72, 0x9c, 0x0d, 0x23, 0x42, - 0x0d, 0xbd, 0xa2, 0xd5, 0x0a, 0x4e, 0x12, 0x21, 0x03, 0xf2, 0xee, 0x30, 0xe8, 0xc9, 0xde, 0xb2, - 0x2a, 0x91, 0x86, 0x07, 0xd9, 0x77, 0x9f, 0xca, 0x99, 0xea, 0x23, 0xd8, 0x98, 0x1d, 0xc5, 0xa1, - 0x7c, 0xc0, 0x42, 0x4e, 0xd1, 0x3f, 0x90, 0x97, 0xd5, 0x3b, 0x81, 0xa7, 0x66, 0xca, 0x36, 0x60, - 0x3c, 0x2a, 0xe7, 0x24, 0xa4, 0xf9, 0xd8, 0xc9, 0xc9, 0x54, 0xd3, 0xab, 0xbe, 0xd7, 0x61, 0xb3, - 0xc5, 0xfd, 0x66, 0xc8, 0x05, 0x0e, 0x45, 0x80, 0x65, 0x2f, 0xa1, 0x88, 0x30, 0x11, 0x7f, 0x72, - 0x25, 0xdb, 0x80, 0x08, 0xee, 0xf5, 0x5c, 0x4c, 0x4e, 0xd5, 0x46, 0x3a, 0x5d, 0xcc, 0xbb, 0x6a, - 0x2d, 0x05, 0x67, 0x3d, 0xcd, 0xc8, 0xce, 0x9e, 0x61, 0xde, 0x9d, 0x6d, 0x5c, 0xbf, 0xab, 0x71, - 0xb4, 0x01, 0xcb, 0x3d, 0xec, 0xd2, 0x5e, 0xb2, 0x93, 0x38, 0x40, 0x5b, 0xb0, 0x12, 0x84, 0x81, - 0xe8, 0xf4, 0xb9, 0x6f, 0x2c, 0xcb, 0xae, 0x9d, 0xbc, 0x8c, 0x5b, 0xdc, 0x47, 0x27, 0x00, 0x2a, - 0xf5, 0x6a, 0x18, 0x7a, 0xdc, 0xc8, 0x55, 0xf4, 0xda, 0x6a, 0x7d, 0xcb, 0x8a, 0xbb, 0xb7, 0xa4, - 0x4f, 0x52, 0x4b, 0x59, 0x47, 0x2c, 0x08, 0x1b, 0xbb, 0x97, 0xa3, 0x72, 0xe6, 0xf3, 0xd7, 0x72, - 0x6d, 0x81, 0x89, 0xe5, 0x07, 0xdc, 0x29, 0x48, 0xfa, 0xa7, 0x92, 0x1d, 0xd5, 0xa1, 0x38, 0x99, - 0x97, 0x07, 0xbe, 0x91, 0x57, 0x0b, 0x5c, 0x1b, 0x8f, 0xca, 0xab, 0x47, 0xc9, 0xff, 0xed, 0xc0, - 0x77, 0x56, 0xc9, 0x34, 0x48, 0xc4, 0x3c, 0x06, 0x73, 0xbe, 0x1c, 0x13, 0x59, 0x0d, 0xc8, 0xe3, - 0x78, 0xbd, 0x4a, 0x97, 0x82, 0x93, 0x86, 0x08, 0x41, 0xd6, 0xc3, 0x02, 0xc7, 0x76, 0x73, 0xd4, - 0xb9, 0xfa, 0x51, 0x07, 0xd4, 0xe2, 0xfe, 0x93, 0x73, 0x4a, 0x86, 0x0f, 0xa3, 0x6d, 0x0b, 0x56, - 0x48, 0x42, 0x9b, 0x18, 0xfd, 0x37, 0xc8, 0x26, 0x14, 0x68, 0x1d, 0x74, 0x29, 0x9e, 0xae, 0x66, - 0x90, 0xc7, 0x3b, 0xcc, 0x93, 0xbd, 0xc3, 0x3c, 0x27, 0x00, 0x9c, 0x86, 0xa9, 0xcc, 0xcb, 0x0f, - 0x20, 0xb3, 0xa4, 0x9f, 0x2f, 0x73, 0x6e, 0x61, 0x99, 0x77, 0xa1, 0xf4, 0xb3, 0x2a, 0x13, 0x89, - 0x53, 0x21, 0xb5, 0xa9, 0x90, 0xf5, 0xeb, 0x25, 0xd0, 0xa5, 0x8d, 0x3b, 0x50, 0x98, 0xde, 0x5a, - 0xff, 0x5a, 0xf3, 0x6f, 0x45, 0x6b, 0xf6, 0x42, 0x28, 0x6d, 0x2f, 0x82, 0x9a, 0x14, 0x7f, 0x0b, - 0x7f, 0xcf, 0xbb, 0x0d, 0xac, 0x7b, 0x48, 0xe6, 0xe0, 0x4b, 0xfb, 0xbf, 0x86, 0x9f, 0x94, 0x7f, - 0x0d, 0x6b, 0xb7, 0xcd, 0xfa, 0xdf, 0x3d, 0x54, 0xb7, 0xb0, 0xa5, 0xfa, 0xe2, 0xd8, 0xb4, 0x64, - 0xe3, 0xf9, 0xe5, 0xd8, 0xd4, 0xae, 0xc6, 0xa6, 0xf6, 0x6d, 0x6c, 0x6a, 0x1f, 0x6e, 0xcc, 0xcc, - 0xd5, 0x8d, 0x99, 0xb9, 0xbe, 0x31, 0x33, 0x2f, 0x0f, 0x66, 0x5c, 0xc1, 0x49, 0x24, 0x7a, 0xd8, - 0xe5, 0x76, 0x5b, 0x15, 0x38, 0xa6, 0xe2, 0x8c, 0x45, 0xa7, 0xf6, 0xf9, 0xe4, 0xcd, 0x0a, 0x42, - 0x41, 0xa3, 0x10, 0xf7, 0x62, 0xb7, 0xb8, 0x39, 0xf5, 0xd2, 0xfc, 0xff, 0x23, 0x00, 0x00, 0xff, - 0xff, 0xab, 0xd9, 0x36, 0x24, 0xdb, 0x06, 0x00, 0x00, + // 820 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xbf, 0x8f, 0xe3, 0x44, + 0x14, 0x8e, 0xcf, 0xf9, 0xb1, 0x7e, 0x1b, 0xee, 0x56, 0xc3, 0x12, 0x7c, 0x41, 0x72, 0xa2, 0x40, + 0x11, 0xa1, 0x3b, 0xfb, 0x36, 0x48, 0x57, 0x1c, 0x55, 0x12, 0x7e, 0xa5, 0xf0, 0x15, 0x0e, 0x08, + 0x89, 0x26, 0x1a, 0xdb, 0x83, 0xe3, 0x5b, 0xc7, 0x0e, 0x9e, 0x09, 0xb9, 0x2d, 0x10, 0x2d, 0x25, + 0x05, 0x7f, 0x00, 0x35, 0x7f, 0xc9, 0xd1, 0x5d, 0x85, 0xb6, 0x0a, 0x28, 0xfb, 0x5f, 0x50, 0xa1, + 0x19, 0xff, 0x58, 0x6f, 0x48, 0x42, 0x58, 0xdd, 0x56, 0xf1, 0xcb, 0xbc, 0xf9, 0xde, 0xf7, 0xde, + 0xf7, 0xcd, 0xd8, 0xd0, 0xa6, 0xc4, 0x89, 0x09, 0x33, 0x9c, 0x68, 0x36, 0x5f, 0x30, 0x62, 0x7c, + 0x7f, 0x66, 0x13, 0x86, 0xcf, 0x8c, 0x19, 0xf5, 0xf4, 0x79, 0x1c, 0xb1, 0x08, 0x35, 0x92, 0x0c, + 0x3d, 0xcd, 0xd0, 0xd3, 0x8c, 0xe6, 0xa9, 0x17, 0x79, 0x91, 0x48, 0x31, 0xf8, 0x53, 0x92, 0xdd, + 0xd4, 0x9c, 0x88, 0xce, 0x22, 0x6a, 0xd8, 0x98, 0x5e, 0x83, 0x39, 0x91, 0x1f, 0x26, 0xeb, 0x9d, + 0xdf, 0x25, 0xa8, 0x9b, 0xd4, 0x1b, 0xb3, 0x28, 0x26, 0xc3, 0xc8, 0x25, 0x68, 0x04, 0x55, 0x4a, + 0x42, 0x97, 0xc4, 0xaa, 0xd4, 0x96, 0xba, 0xf5, 0xc1, 0xd9, 0xdf, 0xab, 0xd6, 0x63, 0xcf, 0x67, + 0xd3, 0x85, 0xcd, 0x4b, 0x1a, 0x29, 0x5e, 0xf2, 0xf3, 0x98, 0xba, 0xe7, 0x06, 0xbb, 0x98, 0x13, + 0xaa, 0xf7, 0x1d, 0xa7, 0xef, 0xba, 0x31, 0xa1, 0xd4, 0x4a, 0x01, 0xd0, 0x53, 0xb8, 0xbf, 0xc4, + 0x74, 0x36, 0xb1, 0x2f, 0x18, 0x99, 0x38, 0x91, 0x4b, 0xd4, 0x7b, 0x02, 0xf2, 0x64, 0xbd, 0x6a, + 0xd5, 0xbf, 0xee, 0x8f, 0xcd, 0xc1, 0x05, 0x13, 0x45, 0xad, 0x3a, 0xcf, 0xcb, 0x22, 0xd4, 0x80, + 0x2a, 0x8d, 0x16, 0xb1, 0x43, 0x54, 0xb9, 0x2d, 0x75, 0x15, 0x2b, 0x8d, 0x90, 0x0a, 0x35, 0x7b, + 0xe1, 0x07, 0x9c, 0x5b, 0x59, 0x2c, 0x64, 0xe1, 0xb3, 0xf2, 0x4f, 0xbf, 0xb6, 0x4a, 0x9d, 0x8f, + 0xe1, 0xb4, 0xd8, 0x8a, 0x45, 0xe8, 0x3c, 0x0a, 0x29, 0x41, 0xef, 0x43, 0x8d, 0x57, 0x9f, 0xf8, + 0xae, 0xe8, 0xa9, 0x3c, 0x80, 0xf5, 0xaa, 0x55, 0xe5, 0x29, 0xa3, 0x4f, 0xac, 0x2a, 0x5f, 0x1a, + 0xb9, 0x9d, 0x3f, 0x64, 0x68, 0x98, 0xd4, 0x1b, 0x85, 0x94, 0xe1, 0x90, 0xf9, 0x98, 0x73, 0x09, + 0x59, 0x8c, 0x1d, 0xf6, 0x26, 0x47, 0xf2, 0x08, 0x90, 0x83, 0x83, 0xc0, 0xc6, 0xce, 0xb9, 0x98, + 0xc8, 0x64, 0x8a, 0xe9, 0x54, 0x8c, 0x45, 0xb1, 0x4e, 0xb2, 0x15, 0xce, 0xec, 0x0b, 0x4c, 0xa7, + 0x45, 0xe2, 0xf2, 0x2e, 0xe2, 0xe8, 0x14, 0x2a, 0x01, 0xb6, 0x49, 0x90, 0xce, 0x24, 0x09, 0xd0, + 0x43, 0x38, 0xf2, 0x43, 0x9f, 0x4d, 0x66, 0xd4, 0x53, 0x2b, 0x9c, 0xb5, 0x55, 0xe3, 0xb1, 0x49, + 0x3d, 0xf4, 0x02, 0x40, 0x2c, 0x7d, 0xbb, 0x08, 0x5d, 0xaa, 0x56, 0xdb, 0x72, 0xf7, 0xb8, 0xf7, + 0x50, 0x4f, 0xd8, 0xeb, 0xdc, 0x27, 0x99, 0xa5, 0xf4, 0x61, 0xe4, 0x87, 0x83, 0x27, 0xaf, 0x56, + 0xad, 0xd2, 0x6f, 0x7f, 0xb6, 0xba, 0x07, 0x74, 0xcc, 0x37, 0x50, 0x4b, 0xe1, 0xf0, 0x9f, 0x71, + 0x74, 0xd4, 0x83, 0x7a, 0xde, 0x2f, 0xf5, 0x3d, 0xb5, 0x26, 0x06, 0xf8, 0x60, 0xbd, 0x6a, 0x1d, + 0x0f, 0xd3, 0xff, 0xc7, 0xbe, 0x67, 0x1d, 0x3b, 0xd7, 0x01, 0xfa, 0x1c, 0x2a, 0xd8, 0x9d, 0xf9, + 0xa1, 0x7a, 0x74, 0xdb, 0x69, 0x27, 0xfb, 0x53, 0x57, 0x3c, 0x07, 0x6d, 0xbb, 0xae, 0xb9, 0x3f, + 0x54, 0xa8, 0xe1, 0x64, 0xa7, 0x10, 0x58, 0xb1, 0xb2, 0x10, 0x21, 0x28, 0xbb, 0x98, 0xe1, 0xc4, + 0xb7, 0x96, 0x78, 0xee, 0xfc, 0x22, 0x03, 0x32, 0xa9, 0xf7, 0xe9, 0x4b, 0xe2, 0x2c, 0xee, 0xc6, + 0x24, 0x26, 0x1c, 0x39, 0x29, 0x6c, 0x7a, 0x62, 0x6e, 0x01, 0x96, 0x43, 0xa0, 0x13, 0x90, 0xb9, + 0x0b, 0x64, 0xd1, 0x03, 0x7f, 0xdc, 0xe1, 0xc2, 0xf2, 0x0e, 0x17, 0xbe, 0x00, 0xa0, 0x24, 0xcc, + 0xfc, 0x52, 0xb9, 0x03, 0xbf, 0x70, 0xf8, 0xed, 0x7e, 0xa9, 0xfe, 0xb7, 0x5f, 0x52, 0x99, 0x9f, + 0x40, 0xf3, 0xdf, 0xaa, 0xe4, 0x12, 0x67, 0x42, 0x4a, 0x05, 0x21, 0x7f, 0x14, 0x3a, 0x9a, 0xbe, + 0x17, 0x17, 0x0f, 0x7b, 0xe3, 0x86, 0x8e, 0x4a, 0x2e, 0x4a, 0x73, 0x43, 0x14, 0xa5, 0x30, 0xe1, + 0x83, 0xce, 0x69, 0x2a, 0x43, 0x39, 0x97, 0x21, 0xa5, 0xbc, 0x41, 0x60, 0x2f, 0x65, 0x0c, 0xf7, + 0x4d, 0xea, 0x7d, 0x35, 0x77, 0x31, 0x23, 0x7d, 0xee, 0xf1, 0x9d, 0x74, 0xdf, 0x03, 0x25, 0x24, + 0xcb, 0x49, 0x72, 0x90, 0x52, 0xbe, 0x21, 0x59, 0x26, 0x9b, 0x8a, 0xbd, 0xc8, 0x37, 0x7b, 0xe9, + 0xa8, 0xe2, 0x1a, 0x2c, 0x94, 0xc8, 0x08, 0x75, 0x86, 0xf0, 0x96, 0x49, 0xbd, 0x61, 0x40, 0x70, + 0xbc, 0xbf, 0xf6, 0x3e, 0xf8, 0x77, 0xe1, 0x9d, 0x1b, 0x20, 0x19, 0x7a, 0xef, 0xf2, 0x1e, 0xc8, + 0xfc, 0x76, 0x9a, 0x80, 0x72, 0xfd, 0x32, 0xfa, 0x40, 0xdf, 0xfe, 0xb2, 0xd3, 0x8b, 0xf7, 0x7c, + 0xf3, 0xd1, 0x21, 0x59, 0xf9, 0x5c, 0x7f, 0x80, 0xb7, 0xb7, 0x5d, 0xf2, 0xfa, 0x1e, 0x90, 0x2d, + 0xf9, 0xcd, 0xa7, 0xff, 0x2f, 0x3f, 0x2f, 0xff, 0x1d, 0x3c, 0xd8, 0xbc, 0x3a, 0x3e, 0xdc, 0x03, + 0xb5, 0x91, 0xdb, 0xec, 0x1d, 0x9e, 0x9b, 0x95, 0x1c, 0x7c, 0xf9, 0x6a, 0xad, 0x49, 0xaf, 0xd7, + 0x9a, 0xf4, 0xd7, 0x5a, 0x93, 0x7e, 0xbe, 0xd2, 0x4a, 0xaf, 0xaf, 0xb4, 0xd2, 0xe5, 0x95, 0x56, + 0xfa, 0xe6, 0x59, 0xe1, 0x8c, 0x52, 0x27, 0x66, 0x01, 0xb6, 0xa9, 0x31, 0x16, 0x05, 0x9e, 0x13, + 0xb6, 0x8c, 0xe2, 0x73, 0xe3, 0x65, 0xfe, 0x29, 0xe2, 0x87, 0x8c, 0xc4, 0x21, 0x0e, 0x92, 0xb3, + 0x6b, 0x57, 0xc5, 0x07, 0xc4, 0x47, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0xbb, 0x3e, 0x4b, 0x85, + 0xb2, 0x08, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -627,6 +958,13 @@ func (m *MsgInstantiateContract) MarshalToSizedBuffer(dAtA []byte) (int, error) _ = i var l int _ = l + if len(m.Admin) > 0 { + i -= len(m.Admin) + copy(dAtA[i:], m.Admin) + i = encodeVarintMsg(dAtA, i, uint64(len(m.Admin))) + i-- + dAtA[i] = 0x42 + } if len(m.CallbackSig) > 0 { i -= len(m.CallbackSig) copy(dAtA[i:], m.CallbackSig) @@ -823,50 +1161,256 @@ func (m *MsgExecuteContractResponse) MarshalToSizedBuffer(dAtA []byte) (int, err return len(dAtA) - i, nil } -func encodeVarintMsg(dAtA []byte, offset int, v uint64) int { - offset -= sovMsg(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ +func (m *MsgMigrateContract) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - dAtA[offset] = uint8(v) - return base + return dAtA[:n], nil } -func (m *MsgStoreCode) Size() (n int) { - if m == nil { - return 0 - } + +func (m *MsgMigrateContract) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgMigrateContract) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = len(m.Sender) - if l > 0 { - n += 1 + l + sovMsg(uint64(l)) + if len(m.Msg) > 0 { + i -= len(m.Msg) + copy(dAtA[i:], m.Msg) + i = encodeVarintMsg(dAtA, i, uint64(len(m.Msg))) + i-- + dAtA[i] = 0x22 } - l = len(m.WASMByteCode) - if l > 0 { - n += 1 + l + sovMsg(uint64(l)) + if m.CodeID != 0 { + i = encodeVarintMsg(dAtA, i, uint64(m.CodeID)) + i-- + dAtA[i] = 0x18 } - l = len(m.Source) - if l > 0 { - n += 1 + l + sovMsg(uint64(l)) + if len(m.Contract) > 0 { + i -= len(m.Contract) + copy(dAtA[i:], m.Contract) + i = encodeVarintMsg(dAtA, i, uint64(len(m.Contract))) + i-- + dAtA[i] = 0x12 } - l = len(m.Builder) - if l > 0 { - n += 1 + l + sovMsg(uint64(l)) + if len(m.Sender) > 0 { + i -= len(m.Sender) + copy(dAtA[i:], m.Sender) + i = encodeVarintMsg(dAtA, i, uint64(len(m.Sender))) + i-- + dAtA[i] = 0xa } - return n + return len(dAtA) - i, nil } -func (m *MsgStoreCodeResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.CodeID != 0 { - n += 1 + sovMsg(uint64(m.CodeID)) +func (m *MsgMigrateContractResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgMigrateContractResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgMigrateContractResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = encodeVarintMsg(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgUpdateAdmin) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgUpdateAdmin) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateAdmin) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Contract) > 0 { + i -= len(m.Contract) + copy(dAtA[i:], m.Contract) + i = encodeVarintMsg(dAtA, i, uint64(len(m.Contract))) + i-- + dAtA[i] = 0x1a + } + if len(m.NewAdmin) > 0 { + i -= len(m.NewAdmin) + copy(dAtA[i:], m.NewAdmin) + i = encodeVarintMsg(dAtA, i, uint64(len(m.NewAdmin))) + i-- + dAtA[i] = 0x12 + } + if len(m.Sender) > 0 { + i -= len(m.Sender) + copy(dAtA[i:], m.Sender) + i = encodeVarintMsg(dAtA, i, uint64(len(m.Sender))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgUpdateAdminResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgUpdateAdminResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateAdminResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgClearAdmin) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgClearAdmin) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgClearAdmin) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Contract) > 0 { + i -= len(m.Contract) + copy(dAtA[i:], m.Contract) + i = encodeVarintMsg(dAtA, i, uint64(len(m.Contract))) + i-- + dAtA[i] = 0x1a + } + if len(m.Sender) > 0 { + i -= len(m.Sender) + copy(dAtA[i:], m.Sender) + i = encodeVarintMsg(dAtA, i, uint64(len(m.Sender))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgClearAdminResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgClearAdminResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgClearAdminResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func encodeVarintMsg(dAtA []byte, offset int, v uint64) int { + offset -= sovMsg(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *MsgStoreCode) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Sender) + if l > 0 { + n += 1 + l + sovMsg(uint64(l)) + } + l = len(m.WASMByteCode) + if l > 0 { + n += 1 + l + sovMsg(uint64(l)) + } + l = len(m.Source) + if l > 0 { + n += 1 + l + sovMsg(uint64(l)) + } + l = len(m.Builder) + if l > 0 { + n += 1 + l + sovMsg(uint64(l)) + } + return n +} + +func (m *MsgStoreCodeResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.CodeID != 0 { + n += 1 + sovMsg(uint64(m.CodeID)) } return n } @@ -906,6 +1450,10 @@ func (m *MsgInstantiateContract) Size() (n int) { if l > 0 { n += 1 + l + sovMsg(uint64(l)) } + l = len(m.Admin) + if l > 0 { + n += 1 + l + sovMsg(uint64(l)) + } return n } @@ -954,33 +1502,377 @@ func (m *MsgExecuteContract) Size() (n int) { n += 1 + l + sovMsg(uint64(l)) } } - l = len(m.CallbackSig) - if l > 0 { - n += 1 + l + sovMsg(uint64(l)) - } - return n -} + l = len(m.CallbackSig) + if l > 0 { + n += 1 + l + sovMsg(uint64(l)) + } + return n +} + +func (m *MsgExecuteContractResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Data) + if l > 0 { + n += 1 + l + sovMsg(uint64(l)) + } + return n +} + +func (m *MsgMigrateContract) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Sender) + if l > 0 { + n += 1 + l + sovMsg(uint64(l)) + } + l = len(m.Contract) + if l > 0 { + n += 1 + l + sovMsg(uint64(l)) + } + if m.CodeID != 0 { + n += 1 + sovMsg(uint64(m.CodeID)) + } + l = len(m.Msg) + if l > 0 { + n += 1 + l + sovMsg(uint64(l)) + } + return n +} + +func (m *MsgMigrateContractResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Data) + if l > 0 { + n += 1 + l + sovMsg(uint64(l)) + } + return n +} + +func (m *MsgUpdateAdmin) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Sender) + if l > 0 { + n += 1 + l + sovMsg(uint64(l)) + } + l = len(m.NewAdmin) + if l > 0 { + n += 1 + l + sovMsg(uint64(l)) + } + l = len(m.Contract) + if l > 0 { + n += 1 + l + sovMsg(uint64(l)) + } + return n +} + +func (m *MsgUpdateAdminResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgClearAdmin) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Sender) + if l > 0 { + n += 1 + l + sovMsg(uint64(l)) + } + l = len(m.Contract) + if l > 0 { + n += 1 + l + sovMsg(uint64(l)) + } + return n +} + +func (m *MsgClearAdminResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func sovMsg(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozMsg(x uint64) (n int) { + return sovMsg(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *MsgStoreCode) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsg + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgStoreCode: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgStoreCode: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsg + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthMsg + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthMsg + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Sender = append(m.Sender[:0], dAtA[iNdEx:postIndex]...) + if m.Sender == nil { + m.Sender = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field WASMByteCode", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsg + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthMsg + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthMsg + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.WASMByteCode = append(m.WASMByteCode[:0], dAtA[iNdEx:postIndex]...) + if m.WASMByteCode == nil { + m.WASMByteCode = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsg + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsg + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsg + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Source = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Builder", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsg + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsg + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsg + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Builder = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipMsg(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMsg + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgStoreCodeResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsg + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgStoreCodeResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgStoreCodeResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CodeID", wireType) + } + m.CodeID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsg + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CodeID |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipMsg(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMsg + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } -func (m *MsgExecuteContractResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Data) - if l > 0 { - n += 1 + l + sovMsg(uint64(l)) + if iNdEx > l { + return io.ErrUnexpectedEOF } - return n -} - -func sovMsg(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozMsg(x uint64) (n int) { - return sovMsg(uint64((x << 1) ^ uint64((int64(x) >> 63)))) + return nil } -func (m *MsgStoreCode) Unmarshal(dAtA []byte) error { +func (m *MsgInstantiateContract) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1003,10 +1895,10 @@ func (m *MsgStoreCode) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgStoreCode: wiretype end group for non-group") + return fmt.Errorf("proto: MsgInstantiateContract: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgStoreCode: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgInstantiateContract: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -1045,9 +1937,9 @@ func (m *MsgStoreCode) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field WASMByteCode", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CallbackCodeHash", wireType) } - var byteLen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowMsg @@ -1057,29 +1949,46 @@ func (m *MsgStoreCode) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthMsg } - postIndex := iNdEx + byteLen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthMsg } if postIndex > l { return io.ErrUnexpectedEOF } - m.WASMByteCode = append(m.WASMByteCode[:0], dAtA[iNdEx:postIndex]...) - if m.WASMByteCode == nil { - m.WASMByteCode = []byte{} - } + m.CallbackCodeHash = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CodeID", wireType) + } + m.CodeID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsg + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CodeID |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Label", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -1107,13 +2016,13 @@ func (m *MsgStoreCode) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Source = string(dAtA[iNdEx:postIndex]) + m.Label = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 4: + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Builder", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field InitMsg", wireType) } - var stringLen uint64 + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowMsg @@ -1123,23 +2032,127 @@ func (m *MsgStoreCode) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if byteLen < 0 { return ErrInvalidLengthMsg } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthMsg } if postIndex > l { return io.ErrUnexpectedEOF } - m.Builder = string(dAtA[iNdEx:postIndex]) + m.InitMsg = append(m.InitMsg[:0], dAtA[iNdEx:postIndex]...) + if m.InitMsg == nil { + m.InitMsg = []byte{} + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InitFunds", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsg + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMsg + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMsg + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.InitFunds = append(m.InitFunds, types.Coin{}) + if err := m.InitFunds[len(m.InitFunds)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CallbackSig", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsg + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthMsg + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthMsg + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CallbackSig = append(m.CallbackSig[:0], dAtA[iNdEx:postIndex]...) + if m.CallbackSig == nil { + m.CallbackSig = []byte{} + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Admin", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsg + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthMsg + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthMsg + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Admin = append(m.Admin[:0], dAtA[iNdEx:postIndex]...) + if m.Admin == nil { + m.Admin = []byte{} + } iNdEx = postIndex default: iNdEx = preIndex @@ -1162,7 +2175,7 @@ func (m *MsgStoreCode) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgStoreCodeResponse) Unmarshal(dAtA []byte) error { +func (m *MsgInstantiateContractResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1185,17 +2198,17 @@ func (m *MsgStoreCodeResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgStoreCodeResponse: wiretype end group for non-group") + return fmt.Errorf("proto: MsgInstantiateContractResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgStoreCodeResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgInstantiateContractResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field CodeID", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) } - m.CodeID = 0 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowMsg @@ -1205,11 +2218,58 @@ func (m *MsgStoreCodeResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.CodeID |= uint64(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsg + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsg + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsg + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } + if byteLen < 0 { + return ErrInvalidLengthMsg + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthMsg + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipMsg(dAtA[iNdEx:]) @@ -1231,7 +2291,7 @@ func (m *MsgStoreCodeResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgInstantiateContract) Unmarshal(dAtA []byte) error { +func (m *MsgExecuteContract) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1254,10 +2314,10 @@ func (m *MsgInstantiateContract) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgInstantiateContract: wiretype end group for non-group") + return fmt.Errorf("proto: MsgExecuteContract: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgInstantiateContract: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgExecuteContract: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -1296,9 +2356,9 @@ func (m *MsgInstantiateContract) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CallbackCodeHash", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Contract", wireType) } - var stringLen uint64 + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowMsg @@ -1308,29 +2368,31 @@ func (m *MsgInstantiateContract) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if byteLen < 0 { return ErrInvalidLengthMsg } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthMsg } if postIndex > l { return io.ErrUnexpectedEOF } - m.CallbackCodeHash = string(dAtA[iNdEx:postIndex]) + m.Contract = append(m.Contract[:0], dAtA[iNdEx:postIndex]...) + if m.Contract == nil { + m.Contract = []byte{} + } iNdEx = postIndex case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field CodeID", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Msg", wireType) } - m.CodeID = 0 + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowMsg @@ -1340,14 +2402,29 @@ func (m *MsgInstantiateContract) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.CodeID |= uint64(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } + if byteLen < 0 { + return ErrInvalidLengthMsg + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthMsg + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Msg = append(m.Msg[:0], dAtA[iNdEx:postIndex]...) + if m.Msg == nil { + m.Msg = []byte{} + } + iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Label", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CallbackCodeHash", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -1375,13 +2452,13 @@ func (m *MsgInstantiateContract) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Label = string(dAtA[iNdEx:postIndex]) + m.CallbackCodeHash = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field InitMsg", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SentFunds", wireType) } - var byteLen int + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowMsg @@ -1391,31 +2468,31 @@ func (m *MsgInstantiateContract) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + if msglen < 0 { return ErrInvalidLengthMsg } - postIndex := iNdEx + byteLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthMsg } if postIndex > l { return io.ErrUnexpectedEOF } - m.InitMsg = append(m.InitMsg[:0], dAtA[iNdEx:postIndex]...) - if m.InitMsg == nil { - m.InitMsg = []byte{} + m.SentFunds = append(m.SentFunds, types.Coin{}) + if err := m.SentFunds[len(m.SentFunds)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field InitFunds", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CallbackSig", wireType) } - var msglen int + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowMsg @@ -1425,29 +2502,79 @@ func (m *MsgInstantiateContract) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + if byteLen < 0 { return ErrInvalidLengthMsg } - postIndex := iNdEx + msglen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthMsg } if postIndex > l { return io.ErrUnexpectedEOF } - m.InitFunds = append(m.InitFunds, types.Coin{}) - if err := m.InitFunds[len(m.InitFunds)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + m.CallbackSig = append(m.CallbackSig[:0], dAtA[iNdEx:postIndex]...) + if m.CallbackSig == nil { + m.CallbackSig = []byte{} } iNdEx = postIndex - case 7: + default: + iNdEx = preIndex + skippy, err := skipMsg(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMsg + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgExecuteContractResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsg + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgExecuteContractResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgExecuteContractResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CallbackSig", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) } var byteLen int for shift := uint(0); ; shift += 7 { @@ -1474,9 +2601,9 @@ func (m *MsgInstantiateContract) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.CallbackSig = append(m.CallbackSig[:0], dAtA[iNdEx:postIndex]...) - if m.CallbackSig == nil { - m.CallbackSig = []byte{} + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} } iNdEx = postIndex default: @@ -1500,7 +2627,7 @@ func (m *MsgInstantiateContract) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgInstantiateContractResponse) Unmarshal(dAtA []byte) error { +func (m *MsgMigrateContract) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1523,15 +2650,47 @@ func (m *MsgInstantiateContractResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgInstantiateContractResponse: wiretype end group for non-group") + return fmt.Errorf("proto: MsgMigrateContract: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgInstantiateContractResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgMigrateContract: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsg + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsg + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsg + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Sender = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Contract", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -1556,12 +2715,115 @@ func (m *MsgInstantiateContractResponse) Unmarshal(dAtA []byte) error { if postIndex < 0 { return ErrInvalidLengthMsg } - if postIndex > l { + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Contract = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CodeID", wireType) + } + m.CodeID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsg + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CodeID |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Msg", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsg + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthMsg + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthMsg + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Msg = append(m.Msg[:0], dAtA[iNdEx:postIndex]...) + if m.Msg == nil { + m.Msg = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipMsg(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMsg + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgMigrateContractResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsg + } + if iNdEx >= l { return io.ErrUnexpectedEOF } - m.Address = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgMigrateContractResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgMigrateContractResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) } @@ -1616,7 +2878,7 @@ func (m *MsgInstantiateContractResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgExecuteContract) Unmarshal(dAtA []byte) error { +func (m *MsgUpdateAdmin) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1639,17 +2901,17 @@ func (m *MsgExecuteContract) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgExecuteContract: wiretype end group for non-group") + return fmt.Errorf("proto: MsgUpdateAdmin: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgExecuteContract: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgUpdateAdmin: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType) } - var byteLen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowMsg @@ -1659,31 +2921,29 @@ func (m *MsgExecuteContract) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthMsg } - postIndex := iNdEx + byteLen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthMsg } if postIndex > l { return io.ErrUnexpectedEOF } - m.Sender = append(m.Sender[:0], dAtA[iNdEx:postIndex]...) - if m.Sender == nil { - m.Sender = []byte{} - } + m.Sender = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Contract", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field NewAdmin", wireType) } - var byteLen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowMsg @@ -1693,31 +2953,29 @@ func (m *MsgExecuteContract) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthMsg } - postIndex := iNdEx + byteLen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthMsg } if postIndex > l { return io.ErrUnexpectedEOF } - m.Contract = append(m.Contract[:0], dAtA[iNdEx:postIndex]...) - if m.Contract == nil { - m.Contract = []byte{} - } + m.NewAdmin = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Msg", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Contract", wireType) } - var byteLen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowMsg @@ -1727,63 +2985,129 @@ func (m *MsgExecuteContract) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthMsg } - postIndex := iNdEx + byteLen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthMsg } if postIndex > l { return io.ErrUnexpectedEOF } - m.Msg = append(m.Msg[:0], dAtA[iNdEx:postIndex]...) - if m.Msg == nil { - m.Msg = []byte{} - } + m.Contract = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CallbackCodeHash", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowMsg - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } + default: + iNdEx = preIndex + skippy, err := skipMsg(dAtA[iNdEx:]) + if err != nil { + return err } - intStringLen := int(stringLen) - if intStringLen < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthMsg } - postIndex := iNdEx + intStringLen - if postIndex < 0 { + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgUpdateAdminResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsg + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgUpdateAdminResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateAdminResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipMsg(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthMsg } - if postIndex > l { + if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } - m.CallbackCodeHash = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgClearAdmin) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsg + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgClearAdmin: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgClearAdmin: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SentFunds", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowMsg @@ -1793,31 +3117,29 @@ func (m *MsgExecuteContract) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthMsg } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthMsg } if postIndex > l { return io.ErrUnexpectedEOF } - m.SentFunds = append(m.SentFunds, types.Coin{}) - if err := m.SentFunds[len(m.SentFunds)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Sender = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 6: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CallbackSig", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Contract", wireType) } - var byteLen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowMsg @@ -1827,25 +3149,23 @@ func (m *MsgExecuteContract) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthMsg } - postIndex := iNdEx + byteLen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthMsg } if postIndex > l { return io.ErrUnexpectedEOF } - m.CallbackSig = append(m.CallbackSig[:0], dAtA[iNdEx:postIndex]...) - if m.CallbackSig == nil { - m.CallbackSig = []byte{} - } + m.Contract = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -1868,7 +3188,7 @@ func (m *MsgExecuteContract) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgExecuteContractResponse) Unmarshal(dAtA []byte) error { +func (m *MsgClearAdminResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1891,46 +3211,12 @@ func (m *MsgExecuteContractResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgExecuteContractResponse: wiretype end group for non-group") + return fmt.Errorf("proto: MsgClearAdminResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgExecuteContractResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgClearAdminResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowMsg - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthMsg - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthMsg - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) - if m.Data == nil { - m.Data = []byte{} - } - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipMsg(dAtA[iNdEx:]) diff --git a/x/compute/internal/types/types.go b/x/compute/internal/types/types.go index 5a540ed7e..0922206d6 100644 --- a/x/compute/internal/types/types.go +++ b/x/compute/internal/types/types.go @@ -60,12 +60,13 @@ func NewCodeInfo(codeHash []byte, creator sdk.AccAddress, source string, builder } // NewContractInfo creates a new instance of a given WASM contract info -func NewContractInfo(codeID uint64, creator sdk.AccAddress, label string, createdAt *AbsoluteTxPosition) ContractInfo { +func NewContractInfo(codeID uint64, creator sdk.AccAddress, admin sdk.AccAddress, label string, createdAt *AbsoluteTxPosition) ContractInfo { return ContractInfo{ CodeID: codeID, Creator: creator, Label: label, Created: createdAt, + Admin: admin, } } diff --git a/x/compute/internal/types/types.pb.go b/x/compute/internal/types/types.pb.go index e4dbe6ceb..bda1cf381 100644 --- a/x/compute/internal/types/types.pb.go +++ b/x/compute/internal/types/types.pb.go @@ -171,13 +171,17 @@ var xxx_messageInfo_ContractCustomInfo proto.InternalMessageInfo // ContractInfo stores a WASM contract instance type ContractInfo struct { - CodeID uint64 `protobuf:"varint,1,opt,name=code_id,json=codeId,proto3" json:"code_id,omitempty"` + // CodeID is the reference to the stored Wasm code + CodeID uint64 `protobuf:"varint,1,opt,name=code_id,json=codeId,proto3" json:"code_id,omitempty"` + // Creator address who initially instantiated the contract Creator github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,2,opt,name=creator,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"creator,omitempty"` - Label string `protobuf:"bytes,4,opt,name=label,proto3" json:"label,omitempty"` - // never show this in query results, just use for sorting - // (Note: when using json tag "-" amino refused to serialize it...) + // Label is mandatory metadata to be stored with a contract instance. + Label string `protobuf:"bytes,4,opt,name=label,proto3" json:"label,omitempty"` + // Created Tx position when the contract was instantiated. Created *AbsoluteTxPosition `protobuf:"bytes,5,opt,name=created,proto3" json:"created,omitempty"` IBCPortID string `protobuf:"bytes,6,opt,name=ibc_port_id,json=ibcPortId,proto3" json:"ibc_port_id,omitempty"` + // Admin is an optional address that can execute migrations + Admin github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,7,opt,name=admin,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"admin,omitempty"` } func (m *ContractInfo) Reset() { *m = ContractInfo{} } @@ -310,54 +314,55 @@ func init() { } var fileDescriptor_8ba7f40a6d1951b3 = []byte{ - // 745 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0x4f, 0x6f, 0xe3, 0x44, - 0x14, 0x8f, 0x9b, 0x34, 0x6d, 0xa6, 0x61, 0x89, 0x86, 0xb2, 0x64, 0x83, 0xe4, 0x04, 0x23, 0xa1, - 0x6a, 0x51, 0x63, 0x75, 0xe1, 0x80, 0x7a, 0xab, 0xe3, 0xa0, 0x66, 0x0b, 0x49, 0x35, 0xdd, 0x5d, - 0xa9, 0x80, 0x14, 0xd9, 0x33, 0x6f, 0x13, 0x2b, 0x8e, 0x27, 0x9a, 0x99, 0x84, 0xf8, 0x1b, 0xa0, - 0x72, 0xe1, 0xc8, 0xa5, 0x12, 0x12, 0x08, 0xed, 0x17, 0xe0, 0x3b, 0xec, 0x71, 0x8f, 0x9c, 0x22, - 0x48, 0xbf, 0x01, 0xc7, 0x3d, 0x21, 0x8f, 0x9d, 0x3f, 0xe2, 0xcf, 0x6d, 0x4f, 0x7e, 0x7f, 0x7e, - 0xf3, 0x7b, 0xef, 0xfd, 0x9e, 0x67, 0x90, 0x25, 0x81, 0x0a, 0x50, 0x36, 0xe5, 0xe3, 0xc9, 0x54, - 0x81, 0x3d, 0x3b, 0xf1, 0x41, 0x79, 0x27, 0xb6, 0x8a, 0x27, 0x20, 0x9b, 0x13, 0xc1, 0x15, 0xc7, - 0xf7, 0x53, 0x4c, 0x33, 0xc3, 0x34, 0x33, 0x4c, 0xed, 0x70, 0xc0, 0x07, 0x5c, 0x43, 0xec, 0xc4, - 0x4a, 0xd1, 0x16, 0x45, 0x6f, 0x9f, 0x51, 0x0a, 0x52, 0x3e, 0x89, 0x27, 0x70, 0xe9, 0x09, 0x6f, - 0x8c, 0x1f, 0xa3, 0xdd, 0x99, 0x17, 0x4e, 0xa1, 0x6a, 0x34, 0x8c, 0xa3, 0x7b, 0x8f, 0xac, 0xe6, - 0x7f, 0x13, 0x36, 0x37, 0xe7, 0x9c, 0xca, 0x5f, 0x8b, 0x7a, 0x39, 0xf6, 0xc6, 0xe1, 0xa9, 0xa5, - 0x8f, 0x5a, 0x24, 0xa5, 0x38, 0x2d, 0xfc, 0xf8, 0x53, 0xdd, 0xb0, 0x7e, 0x35, 0xd0, 0x7e, 0x8b, - 0x33, 0xe8, 0x44, 0xcf, 0x39, 0x7e, 0x1f, 0x95, 0x28, 0x67, 0xd0, 0x1f, 0x7a, 0x72, 0xa8, 0x4b, - 0x94, 0xc9, 0x7e, 0x12, 0x38, 0xf7, 0xe4, 0x10, 0x5f, 0xa0, 0x3d, 0x2a, 0xc0, 0x53, 0x5c, 0x54, - 0x77, 0x92, 0x94, 0x73, 0xf2, 0x7a, 0x51, 0x3f, 0x1e, 0x04, 0x6a, 0x38, 0xf5, 0x93, 0x06, 0x6c, - 0xca, 0xe5, 0x98, 0xcb, 0xec, 0x73, 0x2c, 0xd9, 0x28, 0x9b, 0xfd, 0x8c, 0xd2, 0x33, 0xc6, 0x04, - 0x48, 0x49, 0x56, 0x0c, 0xf8, 0x3e, 0x2a, 0x4a, 0x3e, 0x15, 0x14, 0xaa, 0xf9, 0x86, 0x71, 0x54, - 0x22, 0x99, 0x87, 0xab, 0x68, 0xcf, 0x9f, 0x06, 0x21, 0x03, 0x51, 0x2d, 0xe8, 0xc4, 0xca, 0xb5, - 0xbe, 0x46, 0xb8, 0xc5, 0x23, 0x25, 0x3c, 0xaa, 0x5a, 0x53, 0xa9, 0xf8, 0x58, 0x77, 0x6c, 0xa3, - 0x03, 0x88, 0x68, 0xe8, 0xcd, 0xa0, 0x3f, 0x82, 0x38, 0xed, 0xd9, 0xb9, 0xb7, 0x5c, 0xd4, 0x51, - 0x3b, 0x0d, 0x5f, 0x40, 0x4c, 0x10, 0xac, 0x6d, 0x7c, 0x88, 0x76, 0x43, 0xcf, 0x87, 0x50, 0xcf, - 0x50, 0x22, 0xa9, 0x63, 0x7d, 0xbf, 0x83, 0xca, 0x2b, 0x76, 0xcd, 0xfb, 0x21, 0xda, 0xd3, 0x4a, - 0x04, 0x4c, 0x73, 0x16, 0x1c, 0xb4, 0x5c, 0xd4, 0x8b, 0x5a, 0x28, 0x97, 0x14, 0x93, 0x54, 0x87, - 0xbd, 0x59, 0x45, 0xd6, 0x8d, 0x15, 0xb6, 0x1a, 0xc3, 0x6e, 0x56, 0x02, 0x58, 0x75, 0xb7, 0x61, - 0x1c, 0x1d, 0x3c, 0x7a, 0xf8, 0xbf, 0x2b, 0xf7, 0x25, 0x0f, 0xa7, 0x0a, 0x9e, 0xcc, 0x2f, 0xb9, - 0x0c, 0x54, 0xc0, 0x23, 0xb2, 0x3a, 0x8a, 0x8f, 0xd1, 0x41, 0xe0, 0xd3, 0xfe, 0x84, 0x0b, 0x95, - 0x4c, 0x54, 0x4c, 0x2a, 0x38, 0x6f, 0x2d, 0x17, 0xf5, 0x52, 0xc7, 0x69, 0x5d, 0x72, 0xa1, 0x3a, - 0x2e, 0x29, 0x05, 0x3e, 0xd5, 0x26, 0xb3, 0x08, 0xc2, 0xff, 0x66, 0xc3, 0x1f, 0xa0, 0xb2, 0x1f, - 0x72, 0x3a, 0xea, 0x0f, 0x21, 0x18, 0x0c, 0x95, 0xd6, 0x25, 0x4f, 0x0e, 0x74, 0xec, 0x5c, 0x87, - 0xf0, 0x03, 0xb4, 0xaf, 0xe6, 0xfd, 0x20, 0x62, 0x30, 0xd7, 0x8a, 0x14, 0xc8, 0x9e, 0x9a, 0x77, - 0x12, 0xd7, 0x0a, 0xd0, 0xee, 0x97, 0x9c, 0x41, 0x88, 0x1f, 0xa3, 0xfc, 0xc5, 0x7a, 0x53, 0x9f, - 0xbd, 0x5e, 0xd4, 0x3f, 0xdd, 0x12, 0x4c, 0x41, 0xc4, 0x40, 0x8c, 0x83, 0x48, 0x6d, 0x9b, 0x61, - 0xe0, 0x4b, 0xdb, 0x8f, 0x15, 0xc8, 0xe6, 0x39, 0xcc, 0x9d, 0xc4, 0x20, 0xf9, 0x6c, 0x99, 0xcf, - 0xf4, 0x75, 0xd0, 0xf2, 0x93, 0xd4, 0x79, 0xf8, 0x9b, 0x81, 0xd0, 0xe6, 0x02, 0xe0, 0x8f, 0x50, - 0xe9, 0x69, 0xd7, 0x6d, 0x7f, 0xde, 0xe9, 0xb6, 0xdd, 0x4a, 0xae, 0xf6, 0xde, 0xcd, 0x6d, 0xe3, - 0x9d, 0x4d, 0xfa, 0x69, 0xc4, 0xe0, 0x79, 0x10, 0x01, 0xc3, 0x0d, 0x54, 0xec, 0xf6, 0x9c, 0x9e, - 0x7b, 0x5d, 0x31, 0x6a, 0x87, 0x37, 0xb7, 0x8d, 0xca, 0x06, 0xd4, 0xe5, 0x3e, 0x67, 0x31, 0xfe, - 0x18, 0x95, 0x7b, 0xdd, 0x2f, 0xae, 0xfb, 0x67, 0xae, 0x4b, 0xda, 0x57, 0x57, 0x95, 0x9d, 0xda, - 0x83, 0x9b, 0xdb, 0xc6, 0xbb, 0x1b, 0x5c, 0x2f, 0x0a, 0xe3, 0x6c, 0xb1, 0x49, 0xd9, 0xf6, 0xb3, - 0x36, 0xb9, 0xd6, 0x8c, 0xf9, 0x7f, 0x96, 0x6d, 0xcf, 0x40, 0xc4, 0x09, 0x69, 0x6d, 0xff, 0xbb, - 0x9f, 0xcd, 0xdc, 0x8b, 0x5f, 0xcc, 0x9c, 0xf3, 0xcd, 0xcb, 0x3f, 0xcd, 0xdc, 0x8b, 0xa5, 0x69, - 0xbc, 0x5c, 0x9a, 0xc6, 0xab, 0xa5, 0x69, 0xfc, 0xb1, 0x34, 0x8d, 0x1f, 0xee, 0xcc, 0xdc, 0xab, - 0x3b, 0x33, 0xf7, 0xfb, 0x9d, 0x99, 0xfb, 0xea, 0x74, 0x4b, 0x2a, 0x49, 0x85, 0x0a, 0x3d, 0x5f, - 0xda, 0x57, 0xfa, 0x7f, 0xe8, 0x82, 0xfa, 0x96, 0x8b, 0x91, 0x3d, 0x5f, 0x3f, 0x40, 0x41, 0xa4, - 0x40, 0x44, 0x5e, 0x98, 0xfe, 0x73, 0x7e, 0x51, 0x3f, 0x2a, 0x9f, 0xfc, 0x1d, 0x00, 0x00, 0xff, - 0xff, 0x96, 0xd4, 0xb5, 0xc7, 0xa8, 0x04, 0x00, 0x00, + // 759 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0x4d, 0x6f, 0xe3, 0x44, + 0x18, 0x8e, 0x9b, 0xaf, 0x66, 0x1a, 0x96, 0x68, 0x28, 0x4b, 0x36, 0x48, 0x4e, 0x30, 0x12, 0xaa, + 0x16, 0x35, 0x56, 0x17, 0x0e, 0xa8, 0xb7, 0xba, 0x0e, 0x34, 0x5b, 0x48, 0xab, 0xe9, 0xee, 0x4a, + 0x05, 0xa4, 0xc8, 0x9e, 0x79, 0xb7, 0xb1, 0xe2, 0x78, 0xa2, 0x99, 0x49, 0x88, 0xff, 0x01, 0xea, + 0x89, 0x23, 0x97, 0x4a, 0x48, 0x20, 0xb4, 0x7f, 0x80, 0xff, 0xb0, 0xc7, 0x3d, 0x70, 0xe0, 0x14, + 0x41, 0xfa, 0x0f, 0x38, 0xf6, 0x84, 0x3c, 0x76, 0x3e, 0xc4, 0xc7, 0x05, 0xed, 0xc9, 0xef, 0xe7, + 0xf3, 0x3e, 0xef, 0xf3, 0xda, 0x46, 0x96, 0x04, 0x2a, 0x40, 0xd9, 0x94, 0x8f, 0xc6, 0x13, 0x05, + 0xf6, 0xf4, 0xc0, 0x07, 0xe5, 0x1d, 0xd8, 0x2a, 0x1e, 0x83, 0x6c, 0x8f, 0x05, 0x57, 0x1c, 0xdf, + 0x4f, 0x6b, 0xda, 0x59, 0x4d, 0x3b, 0xab, 0x69, 0xec, 0x5e, 0xf1, 0x2b, 0xae, 0x4b, 0xec, 0xc4, + 0x4a, 0xab, 0x2d, 0x8a, 0xde, 0x3c, 0xa2, 0x14, 0xa4, 0x7c, 0x12, 0x8f, 0xe1, 0xdc, 0x13, 0xde, + 0x08, 0x3f, 0x46, 0xc5, 0xa9, 0x17, 0x4e, 0xa0, 0x6e, 0xb4, 0x8c, 0xbd, 0x7b, 0x8f, 0xac, 0xf6, + 0xbf, 0x03, 0xb6, 0xd7, 0x7d, 0x4e, 0xed, 0xcf, 0x79, 0xb3, 0x1a, 0x7b, 0xa3, 0xf0, 0xd0, 0xd2, + 0xad, 0x16, 0x49, 0x21, 0x0e, 0x0b, 0xdf, 0xff, 0xd0, 0x34, 0xac, 0x9f, 0x0d, 0xb4, 0x7d, 0xcc, + 0x19, 0x74, 0xa3, 0xe7, 0x1c, 0xbf, 0x8b, 0x2a, 0x94, 0x33, 0xe8, 0x0f, 0x3c, 0x39, 0xd0, 0x23, + 0xaa, 0x64, 0x3b, 0x09, 0x9c, 0x78, 0x72, 0x80, 0x4f, 0x51, 0x99, 0x0a, 0xf0, 0x14, 0x17, 0xf5, + 0xad, 0x24, 0xe5, 0x1c, 0xdc, 0xcd, 0x9b, 0xfb, 0x57, 0x81, 0x1a, 0x4c, 0xfc, 0x84, 0x80, 0x4d, + 0xb9, 0x1c, 0x71, 0x99, 0x3d, 0xf6, 0x25, 0x1b, 0x66, 0xbb, 0x1f, 0x51, 0x7a, 0xc4, 0x98, 0x00, + 0x29, 0xc9, 0x12, 0x01, 0xdf, 0x47, 0x25, 0xc9, 0x27, 0x82, 0x42, 0x3d, 0xdf, 0x32, 0xf6, 0x2a, + 0x24, 0xf3, 0x70, 0x1d, 0x95, 0xfd, 0x49, 0x10, 0x32, 0x10, 0xf5, 0x82, 0x4e, 0x2c, 0x5d, 0xeb, + 0x2b, 0x84, 0x8f, 0x79, 0xa4, 0x84, 0x47, 0xd5, 0xf1, 0x44, 0x2a, 0x3e, 0xd2, 0x8c, 0x6d, 0xb4, + 0x03, 0x11, 0x0d, 0xbd, 0x29, 0xf4, 0x87, 0x10, 0xa7, 0x9c, 0x9d, 0x7b, 0x8b, 0x79, 0x13, 0x75, + 0xd2, 0xf0, 0x29, 0xc4, 0x04, 0xc1, 0xca, 0xc6, 0xbb, 0xa8, 0x18, 0x7a, 0x3e, 0x84, 0x7a, 0x87, + 0x0a, 0x49, 0x1d, 0xeb, 0xd7, 0x2d, 0x54, 0x5d, 0xa2, 0x6b, 0xdc, 0xf7, 0x51, 0x59, 0x2b, 0x11, + 0x30, 0x8d, 0x59, 0x70, 0xd0, 0x62, 0xde, 0x2c, 0x69, 0xa1, 0x5c, 0x52, 0x4a, 0x52, 0x5d, 0xf6, + 0x7a, 0x15, 0x59, 0x11, 0x2b, 0x6c, 0x10, 0xc3, 0x6e, 0x36, 0x02, 0x58, 0xbd, 0xd8, 0x32, 0xf6, + 0x76, 0x1e, 0x3d, 0xfc, 0xcf, 0x93, 0xfb, 0x92, 0x87, 0x13, 0x05, 0x4f, 0x66, 0xe7, 0x5c, 0x06, + 0x2a, 0xe0, 0x11, 0x59, 0xb6, 0xe2, 0x7d, 0xb4, 0x13, 0xf8, 0xb4, 0x3f, 0xe6, 0x42, 0x25, 0x1b, + 0x95, 0x92, 0x09, 0xce, 0x1b, 0x8b, 0x79, 0xb3, 0xd2, 0x75, 0x8e, 0xcf, 0xb9, 0x50, 0x5d, 0x97, + 0x54, 0x02, 0x9f, 0x6a, 0x93, 0xe1, 0xcf, 0x50, 0xd1, 0x63, 0xa3, 0x20, 0xaa, 0x97, 0xff, 0xef, + 0x56, 0x69, 0xbf, 0x45, 0x10, 0xfe, 0x27, 0x2d, 0xfc, 0x1e, 0xaa, 0xfa, 0x21, 0xa7, 0xc3, 0xfe, + 0x00, 0x82, 0xab, 0x81, 0xd2, 0x02, 0xe7, 0xc9, 0x8e, 0x8e, 0x9d, 0xe8, 0x10, 0x7e, 0x80, 0xb6, + 0xd5, 0xac, 0x1f, 0x44, 0x0c, 0x66, 0x5a, 0xda, 0x02, 0x29, 0xab, 0x59, 0x37, 0x71, 0xad, 0x00, + 0x15, 0xbf, 0xe0, 0x0c, 0x42, 0xfc, 0x18, 0xe5, 0x4f, 0x57, 0x27, 0xff, 0xe4, 0x6e, 0xde, 0xfc, + 0x78, 0x83, 0xa3, 0x82, 0x88, 0x81, 0x18, 0x05, 0x91, 0xda, 0x34, 0xc3, 0xc0, 0x97, 0xb6, 0x1f, + 0x2b, 0x90, 0xed, 0x13, 0x98, 0x39, 0x89, 0x41, 0xf2, 0xd9, 0x5b, 0xf1, 0x4c, 0x7f, 0x57, 0xfa, + 0x8e, 0x24, 0x75, 0x1e, 0xfe, 0x62, 0x20, 0xb4, 0xfe, 0x92, 0xf0, 0x07, 0xa8, 0xf2, 0xb4, 0xe7, + 0x76, 0x3e, 0xed, 0xf6, 0x3a, 0x6e, 0x2d, 0xd7, 0x78, 0xe7, 0xfa, 0xa6, 0xf5, 0xd6, 0x3a, 0xfd, + 0x34, 0x62, 0xf0, 0x3c, 0x88, 0x80, 0xe1, 0x16, 0x2a, 0xf5, 0xce, 0x9c, 0x33, 0xf7, 0xb2, 0x66, + 0x34, 0x76, 0xaf, 0x6f, 0x5a, 0xb5, 0x75, 0x51, 0x8f, 0xfb, 0x9c, 0xc5, 0xf8, 0x43, 0x54, 0x3d, + 0xeb, 0x7d, 0x7e, 0xd9, 0x3f, 0x72, 0x5d, 0xd2, 0xb9, 0xb8, 0xa8, 0x6d, 0x35, 0x1e, 0x5c, 0xdf, + 0xb4, 0xde, 0x5e, 0xd7, 0x9d, 0x45, 0x61, 0x9c, 0x69, 0x99, 0x8c, 0xed, 0x3c, 0xeb, 0x90, 0x4b, + 0x8d, 0x98, 0xff, 0xfb, 0xd8, 0xce, 0x14, 0x44, 0x9c, 0x80, 0x36, 0xb6, 0xbf, 0xfd, 0xd1, 0xcc, + 0xbd, 0xf8, 0xc9, 0xcc, 0x39, 0x5f, 0xbf, 0xfc, 0xc3, 0xcc, 0xbd, 0x58, 0x98, 0xc6, 0xcb, 0x85, + 0x69, 0xbc, 0x5a, 0x98, 0xc6, 0xef, 0x0b, 0xd3, 0xf8, 0xee, 0xd6, 0xcc, 0xbd, 0xba, 0x35, 0x73, + 0xbf, 0xdd, 0x9a, 0xb9, 0x2f, 0x0f, 0x37, 0xa4, 0x92, 0x54, 0xa8, 0xd0, 0xf3, 0xa5, 0x7d, 0xa1, + 0x5f, 0xac, 0x1e, 0xa8, 0x6f, 0xb8, 0x18, 0xda, 0xb3, 0xd5, 0x9f, 0x2c, 0x88, 0x14, 0x88, 0xc8, + 0x0b, 0xd3, 0x33, 0xfb, 0x25, 0xfd, 0x77, 0xfa, 0xe8, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xed, + 0xe3, 0x3f, 0x30, 0xf1, 0x04, 0x00, 0x00, } func (this *AccessTypeParam) Equal(that interface{}) bool { @@ -478,6 +483,9 @@ func (this *ContractInfo) Equal(that interface{}) bool { if this.IBCPortID != that1.IBCPortID { return false } + if !bytes.Equal(this.Admin, that1.Admin) { + return false + } return true } func (this *AbsoluteTxPosition) Equal(that interface{}) bool { @@ -670,6 +678,13 @@ func (m *ContractInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.Admin) > 0 { + i -= len(m.Admin) + copy(dAtA[i:], m.Admin) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Admin))) + i-- + dAtA[i] = 0x3a + } if len(m.IBCPortID) > 0 { i -= len(m.IBCPortID) copy(dAtA[i:], m.IBCPortID) @@ -871,6 +886,10 @@ func (m *ContractInfo) Size() (n int) { if l > 0 { n += 1 + l + sovTypes(uint64(l)) } + l = len(m.Admin) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } return n } @@ -1461,6 +1480,40 @@ func (m *ContractInfo) Unmarshal(dAtA []byte) error { } m.IBCPortID = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Admin", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Admin = append(m.Admin[:0], dAtA[iNdEx:postIndex]...) + if m.Admin == nil { + m.Admin = []byte{} + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) From 14e05eb5234df74ae660b0e95ebe589180d4745a Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Mon, 6 Feb 2023 21:38:03 +0200 Subject: [PATCH 003/164] Add MigrateContract, UpdateAdmin & ClearAdmin to MsgServer Also implement UpdateAdmin & ClearAdmin in keeper --- proto/secret/compute/v1beta1/types.proto | 31 ++ .../internal/keeper/distribution_test.go | 2 +- x/compute/internal/keeper/gov_test.go | 4 +- x/compute/internal/keeper/keeper.go | 16 + x/compute/internal/keeper/keeper_test.go | 10 +- x/compute/internal/keeper/mint_test.go | 2 +- x/compute/internal/keeper/msg_server.go | 92 ++++ x/compute/internal/keeper/querier_test.go | 6 +- .../keeper/secret_contracts_init_test.go | 14 +- .../keeper/secret_contracts_utils_test.go | 2 +- x/compute/internal/keeper/staking_test.go | 4 +- x/compute/internal/keeper/test_common.go | 2 +- x/compute/internal/types/events.go | 27 +- x/compute/internal/types/msg.go | 107 ++++ x/compute/internal/types/types.go | 25 + x/compute/internal/types/types.pb.go | 458 ++++++++++++++++-- 16 files changed, 716 insertions(+), 86 deletions(-) diff --git a/proto/secret/compute/v1beta1/types.proto b/proto/secret/compute/v1beta1/types.proto index c5c9400a0..84d690f61 100644 --- a/proto/secret/compute/v1beta1/types.proto +++ b/proto/secret/compute/v1beta1/types.proto @@ -63,4 +63,35 @@ message Model { bytes Key = 1 [(gogoproto.casttype) = "github.com/tendermint/tendermint/libs/bytes.HexBytes"]; // base64-encode raw value bytes Value = 2; +} + +// ContractCodeHistoryOperationType actions that caused a code change +enum ContractCodeHistoryOperationType { + option (gogoproto.goproto_enum_prefix) = false; + // ContractCodeHistoryOperationTypeUnspecified placeholder for empty value + CONTRACT_CODE_HISTORY_OPERATION_TYPE_UNSPECIFIED = 0 + [ (gogoproto.enumvalue_customname) = + "ContractCodeHistoryOperationTypeUnspecified" ]; + // ContractCodeHistoryOperationTypeInit on chain contract instantiation + CONTRACT_CODE_HISTORY_OPERATION_TYPE_INIT = 1 + [ (gogoproto.enumvalue_customname) = + "ContractCodeHistoryOperationTypeInit" ]; + // ContractCodeHistoryOperationTypeMigrate code migration + CONTRACT_CODE_HISTORY_OPERATION_TYPE_MIGRATE = 2 + [ (gogoproto.enumvalue_customname) = + "ContractCodeHistoryOperationTypeMigrate" ]; + // ContractCodeHistoryOperationTypeGenesis based on genesis data + CONTRACT_CODE_HISTORY_OPERATION_TYPE_GENESIS = 3 + [ (gogoproto.enumvalue_customname) = + "ContractCodeHistoryOperationTypeGenesis" ]; +} + +// ContractCodeHistoryEntry metadata to a contract. +message ContractCodeHistoryEntry { + ContractCodeHistoryOperationType operation = 1; + // CodeID is the reference to the stored WASM code + uint64 code_id = 2 [ (gogoproto.customname) = "CodeID" ]; + // Updated Tx position when the operation was executed. + AbsoluteTxPosition updated = 3; + bytes msg = 4; } \ No newline at end of file diff --git a/x/compute/internal/keeper/distribution_test.go b/x/compute/internal/keeper/distribution_test.go index d81ef3938..d5ce2f440 100644 --- a/x/compute/internal/keeper/distribution_test.go +++ b/x/compute/internal/keeper/distribution_test.go @@ -80,7 +80,7 @@ func TestDistributionRewards(t *testing.T) { require.NoError(t, err) ctx = PrepareInitSignedTx(t, keeper, ctx, creator, creatorPrivKey, initBz, govId, nil) - govAddr, _, err := keeper.Instantiate(ctx, govId, creator, initBz, "gidi gov", nil, nil) + govAddr, _, err := keeper.Instantiate(ctx, govId, creator, nil, initBz, "gidi gov", nil, nil) require.NoError(t, err) require.NotEmpty(t, govAddr) diff --git a/x/compute/internal/keeper/gov_test.go b/x/compute/internal/keeper/gov_test.go index e40133582..76589f77f 100644 --- a/x/compute/internal/keeper/gov_test.go +++ b/x/compute/internal/keeper/gov_test.go @@ -69,7 +69,7 @@ func TestGovQueryProposals(t *testing.T) { require.NoError(t, err) ctx = PrepareInitSignedTx(t, keeper, ctx, creator, creatorPrivKey, initBz, govId, nil) - govAddr, _, err := keeper.Instantiate(ctx, govId, creator, initBz, "gidi gov", nil, nil) + govAddr, _, err := keeper.Instantiate(ctx, govId, creator, nil, initBz, "gidi gov", nil, nil) require.NoError(t, err) require.NotEmpty(t, govAddr) @@ -137,7 +137,7 @@ func TestGovVote(t *testing.T) { require.NoError(t, err) ctx = PrepareInitSignedTx(t, keeper, ctx, creator, creatorPrivKey, initBz, govId, deposit2) - govAddr, _, err := keeper.Instantiate(ctx, govId, creator, initBz, "gidi gov", deposit2, nil) + govAddr, _, err := keeper.Instantiate(ctx, govId, creator, nil, initBz, "gidi gov", deposit2, nil) require.NoError(t, err) require.NotEmpty(t, govAddr) diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index 99e4b4825..9afb3d7cc 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -1052,3 +1052,19 @@ func (k Keeper) reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply v1w return nil, sdkerrors.Wrap(types.ErrReplyFailed, fmt.Sprintf("cannot detect response type: %+v", res)) } } + +func (k Keeper) UpdateContractAdmin(ctx sdk.Context, contractAddress, caller, newAdmin sdk.AccAddress) error { + contractInfo := k.GetContractInfo(ctx, contractAddress) + if contractInfo == nil { + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "unknown contract") + } + contractInfo.Admin = newAdmin + k.setContractInfo(ctx, contractAddress, contractInfo) + ctx.EventManager().EmitEvent(sdk.NewEvent( + types.EventTypeUpdateContractAdmin, + sdk.NewAttribute(types.AttributeKeyContractAddr, contractAddress.String()), + sdk.NewAttribute(types.AttributeKeyNewAdmin, newAdmin.String()), + )) + + return nil +} diff --git a/x/compute/internal/keeper/keeper_test.go b/x/compute/internal/keeper/keeper_test.go index 6cddf283b..3b83bd2a2 100644 --- a/x/compute/internal/keeper/keeper_test.go +++ b/x/compute/internal/keeper/keeper_test.go @@ -286,7 +286,7 @@ func TestInstantiate(t *testing.T) { ctx = ctx.WithTxBytes(txBytes) // create with no balance is also legal - contractAddr, _, err := keeper.Instantiate(ctx, contractID, creator /* , nil */, initMsgBz, "demo contract 1", nil, nil) + contractAddr, _, err := keeper.Instantiate(ctx, contractID, creator, nil, initMsgBz, "demo contract 1", nil, nil) require.NoError(t, err) require.Equal(t, "secret18vd8fpwxzck93qlwghaj6arh4p7c5n8978vsyg", contractAddr.String()) @@ -303,7 +303,7 @@ func TestInstantiate(t *testing.T) { require.Equal(t, info.Label, "demo contract 1") // test that creating again with the same label will fail - _, _, err = keeper.Instantiate(ctx, contractID, creator /* , nil */, initMsgBz, "demo contract 1", nil, nil) + _, _, err = keeper.Instantiate(ctx, contractID, creator, nil, initMsgBz, "demo contract 1", nil, nil) require.Error(t, err) } @@ -402,7 +402,7 @@ func TestInstantiateWithNonExistingCodeID(t *testing.T) { ctx = ctx.WithTxBytes(txBytes) - addr, _, err := keeper.Instantiate(ctx, nonExistingCodeID, creator /* , nil */, initMsgBz, "demo contract 2", nil, nil) + addr, _, err := keeper.Instantiate(ctx, nonExistingCodeID, creator, nil, initMsgBz, "demo contract 2", nil, nil) require.True(t, types.ErrNotFound.Is(err), err) require.Nil(t, addr) } @@ -452,7 +452,7 @@ func TestExecute(t *testing.T) { ctx = PrepareInitSignedTx(t, keeper, ctx, creator, creatorPrivKey, initMsgBz, contractID, deposit) // create with no balance is also legal - addr, _, err := keeper.Instantiate(ctx, contractID, creator /* , nil */, initMsgBz, "demo contract 1", deposit, nil) + addr, _, err := keeper.Instantiate(ctx, contractID, creator, nil, initMsgBz, "demo contract 1", deposit, nil) require.NoError(t, err) @@ -751,7 +751,7 @@ func TestExecuteWithCpuLoop(t *testing.T) { ctx = ctx.WithTxBytes(txBytes) - addr, _, err := keeper.Instantiate(ctx, contractID, creator /* , nil */, msgBz, "demo contract 5", deposit, nil) + addr, _, err := keeper.Instantiate(ctx, contractID, creator, nil, msgBz, "demo contract 5", deposit, nil) require.NoError(t, err) // make sure we set a limit before calling diff --git a/x/compute/internal/keeper/mint_test.go b/x/compute/internal/keeper/mint_test.go index 36a68478f..4eae58d04 100644 --- a/x/compute/internal/keeper/mint_test.go +++ b/x/compute/internal/keeper/mint_test.go @@ -76,7 +76,7 @@ func TestMintQuerier(t *testing.T) { require.NoError(t, err) ctx = PrepareInitSignedTx(t, keeper, ctx, creator, creatorPrivKey, initBz, govId, nil) - govAddr, _, err := keeper.Instantiate(ctx, govId, creator, initBz, "gidi gov", nil, nil) + govAddr, _, err := keeper.Instantiate(ctx, govId, creator, nil, initBz, "gidi gov", nil, nil) require.NoError(t, err) require.NotEmpty(t, govAddr) diff --git a/x/compute/internal/keeper/msg_server.go b/x/compute/internal/keeper/msg_server.go index 28dd9d998..f865492a0 100644 --- a/x/compute/internal/keeper/msg_server.go +++ b/x/compute/internal/keeper/msg_server.go @@ -5,6 +5,7 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/scrtlabs/SecretNetwork/x/compute/internal/types" ) @@ -88,3 +89,94 @@ func (m msgServer) ExecuteContract(goCtx context.Context, msg *types.MsgExecuteC Data: data.Data, }, nil } + +func (m msgServer) MigrateContract(goCtx context.Context, msg *types.MsgMigrateContract) (*types.MsgMigrateContractResponse, error) { + if err := msg.ValidateBasic(); err != nil { + return nil, err + } + + ctx := sdk.UnwrapSDKContext(goCtx) + senderAddr, err := sdk.AccAddressFromBech32(msg.Sender) + if err != nil { + return nil, sdkerrors.Wrap(err, "sender") + } + contractAddr, err := sdk.AccAddressFromBech32(msg.Contract) + if err != nil { + return nil, sdkerrors.Wrap(err, "contract") + } + + ctx.EventManager().EmitEvent(sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender), + )) + + data, err := m.keeper.Migrate(ctx, contractAddr, senderAddr, msg.CodeID, msg.Msg) + if err != nil { + return nil, err + } + + return &types.MsgMigrateContractResponse{ + Data: data, + }, nil +} + +func (m msgServer) UpdateAdmin(goCtx context.Context, msg *types.MsgUpdateAdmin) (*types.MsgUpdateAdminResponse, error) { + if err := msg.ValidateBasic(); err != nil { + return nil, err + } + + ctx := sdk.UnwrapSDKContext(goCtx) + senderAddr, err := sdk.AccAddressFromBech32(msg.Sender) + if err != nil { + return nil, sdkerrors.Wrap(err, "sender") + } + contractAddr, err := sdk.AccAddressFromBech32(msg.Contract) + if err != nil { + return nil, sdkerrors.Wrap(err, "contract") + } + newAdminAddr, err := sdk.AccAddressFromBech32(msg.NewAdmin) + if err != nil { + return nil, sdkerrors.Wrap(err, "new admin") + } + + ctx.EventManager().EmitEvent(sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender), + )) + + if err := m.keeper.UpdateContractAdmin(ctx, contractAddr, senderAddr, newAdminAddr); err != nil { + return nil, err + } + + return &types.MsgUpdateAdminResponse{}, nil +} + +func (m msgServer) ClearAdmin(goCtx context.Context, msg *types.MsgClearAdmin) (*types.MsgClearAdminResponse, error) { + if err := msg.ValidateBasic(); err != nil { + return nil, err + } + + ctx := sdk.UnwrapSDKContext(goCtx) + senderAddr, err := sdk.AccAddressFromBech32(msg.Sender) + if err != nil { + return nil, sdkerrors.Wrap(err, "sender") + } + contractAddr, err := sdk.AccAddressFromBech32(msg.Contract) + if err != nil { + return nil, sdkerrors.Wrap(err, "contract") + } + + ctx.EventManager().EmitEvent(sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender), + )) + + if err := m.keeper.UpdateContractAdmin(ctx, contractAddr, senderAddr, nil); err != nil { + return nil, err + } + + return &types.MsgClearAdminResponse{}, nil +} diff --git a/x/compute/internal/keeper/querier_test.go b/x/compute/internal/keeper/querier_test.go index f4e88048d..cc0523c10 100644 --- a/x/compute/internal/keeper/querier_test.go +++ b/x/compute/internal/keeper/querier_test.go @@ -65,7 +65,7 @@ func TestQueryContractLabel(t *testing.T) { ctx = PrepareInitSignedTx(t, keeper, ctx, creator, privCreator, initMsgBz, contractID, deposit) - addr, _, err := keeper.Instantiate(ctx, contractID, creator /* nil,*/, initMsgBz, label, deposit, nil) + addr, _, err := keeper.Instantiate(ctx, contractID, creator, nil, initMsgBz, label, deposit, nil) require.NoError(t, err) // this gets us full error, not redacted sdk.Error @@ -165,7 +165,7 @@ func TestQueryContractState(t *testing.T) { initMsgBz, err = wasmCtx.Encrypt(msg.Serialize()) - addr, _, err := keeper.Instantiate(ctx, contractID, creator /* nil,*/, initMsgBz, "demo contract to query", deposit, nil) + addr, _, err := keeper.Instantiate(ctx, contractID, creator, nil, initMsgBz, "demo contract to query", deposit, nil) require.NoError(t, err) contractModel := []types.Model{ @@ -343,7 +343,7 @@ func TestListContractByCodeOrdering(t *testing.T) { ctx = ctx.WithTxBytes(txBytes) - _, _, err = keeper.Instantiate(ctx, codeID, creator /* nil,*/, initMsgBz, fmt.Sprintf("contract %d", i), topUp, nil) + _, _, err = keeper.Instantiate(ctx, codeID, creator, nil, initMsgBz, fmt.Sprintf("contract %d", i), topUp, nil) require.NoError(t, err) } diff --git a/x/compute/internal/keeper/secret_contracts_init_test.go b/x/compute/internal/keeper/secret_contracts_init_test.go index b47e41b7a..9a76c8ef1 100644 --- a/x/compute/internal/keeper/secret_contracts_init_test.go +++ b/x/compute/internal/keeper/secret_contracts_init_test.go @@ -167,7 +167,7 @@ func TestInitNotEncryptedInputError(t *testing.T) { ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privKey, initMsg, codeID, nil) // init - _, _, err := keeper.Instantiate(ctx, codeID, walletA /* nil, */, initMsg, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) + _, _, err := keeper.Instantiate(ctx, codeID, walletA, nil, initMsg, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) require.Error(t, err) require.Contains(t, err.Error(), "failed to decrypt data") @@ -554,7 +554,7 @@ func TestCodeHashInvalid(t *testing.T) { enc, _ := wasmCtx.Encrypt(initMsg) ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privWalletA, enc, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) - _, _, err := keeper.Instantiate(ctx, codeID, walletA /* nil, */, enc, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) + _, _, err := keeper.Instantiate(ctx, codeID, walletA, nil, enc, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) require.Error(t, err) require.Contains(t, err.Error(), "failed to validate transaction") }) @@ -570,7 +570,7 @@ func TestCodeHashEmpty(t *testing.T) { enc, _ := wasmCtx.Encrypt(initMsg) ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privWalletA, enc, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) - _, _, err := keeper.Instantiate(ctx, codeID, walletA /* nil, */, enc, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) + _, _, err := keeper.Instantiate(ctx, codeID, walletA, nil, enc, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) require.Error(t, err) require.Contains(t, err.Error(), "failed to validate transaction") }) @@ -586,7 +586,7 @@ func TestCodeHashNotHex(t *testing.T) { enc, _ := wasmCtx.Encrypt(initMsg) ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privWalletA, enc, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) - _, _, err := keeper.Instantiate(ctx, codeID, walletA /* nil, */, enc, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) + _, _, err := keeper.Instantiate(ctx, codeID, walletA, nil, enc, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) require.Error(t, err) require.Contains(t, err.Error(), "failed to validate transaction") }) @@ -603,7 +603,7 @@ func TestCodeHashTooSmall(t *testing.T) { enc, _ := wasmCtx.Encrypt(initMsg) ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privWalletA, enc, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) - _, _, err := keeper.Instantiate(ctx, codeID, walletA /* nil, */, enc, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) + _, _, err := keeper.Instantiate(ctx, codeID, walletA, nil, enc, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) require.Error(t, err) require.Contains(t, err.Error(), "failed to validate transaction") }) @@ -620,7 +620,7 @@ func TestCodeHashTooBig(t *testing.T) { enc, _ := wasmCtx.Encrypt(initMsg) ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privWalletA, enc, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) - _, _, err := keeper.Instantiate(ctx, codeID, walletA /* nil, */, enc, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) + _, _, err := keeper.Instantiate(ctx, codeID, walletA, nil, enc, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) require.Error(t, err) initErr := extractInnerError(t, err, enc[0:32], true, testContract.IsCosmWasmV1) @@ -640,7 +640,7 @@ func TestCodeHashWrong(t *testing.T) { enc, _ := wasmCtx.Encrypt(initMsg) ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privWalletA, enc, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) - _, _, err := keeper.Instantiate(ctx, codeID, walletA /* nil, */, enc, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) + _, _, err := keeper.Instantiate(ctx, codeID, walletA, nil, enc, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) require.Error(t, err) require.Contains(t, err.Error(), "failed to validate transaction") }) diff --git a/x/compute/internal/keeper/secret_contracts_utils_test.go b/x/compute/internal/keeper/secret_contracts_utils_test.go index a976ceee0..5fefc7445 100644 --- a/x/compute/internal/keeper/secret_contracts_utils_test.go +++ b/x/compute/internal/keeper/secret_contracts_utils_test.go @@ -539,7 +539,7 @@ func initHelperImpl( ctx = PrepareInitSignedTx(t, keeper, ctx, creator, creatorPrivKey, initMsgBz, codeID, sentFunds) // make the label a random base64 string, because why not? - contractAddress, _, err := keeper.Instantiate(ctx, codeID, creator /* nil,*/, initMsgBz, base64.RawURLEncoding.EncodeToString(nonce), sentFunds, nil) + contractAddress, _, err := keeper.Instantiate(ctx, codeID, creator, nil, initMsgBz, base64.RawURLEncoding.EncodeToString(nonce), sentFunds, nil) if wasmCallCount < 0 { // default, just check that at least 1 call happened diff --git a/x/compute/internal/keeper/staking_test.go b/x/compute/internal/keeper/staking_test.go index 9b892fee1..f4628db30 100644 --- a/x/compute/internal/keeper/staking_test.go +++ b/x/compute/internal/keeper/staking_test.go @@ -135,7 +135,7 @@ func TestInitializeStaking(t *testing.T) { require.NoError(t, err) ctx = PrepareInitSignedTx(t, keeper, ctx, creator, creatorPrivKey, initBz, stakingID, nil) - stakingAddr, _, err := keeper.Instantiate(ctx, stakingID, creator /* , nil */, initBz, "staking derivates - DRV", nil, nil) + stakingAddr, _, err := keeper.Instantiate(ctx, stakingID, creator, nil, initBz, "staking derivates - DRV", nil, nil) require.NoError(t, err) require.NotEmpty(t, stakingAddr) @@ -229,7 +229,7 @@ func initializeStaking(t *testing.T) initInfo { require.NoError(t, err) ctx = PrepareInitSignedTx(t, keeper, ctx, creator, creatorPrivKey, initBz, stakingID, nil) - stakingAddr, _, err := keeper.Instantiate(ctx, stakingID, creator /* , nil */, initBz, "staking derivates - DRV", nil, nil) + stakingAddr, _, err := keeper.Instantiate(ctx, stakingID, creator, nil, initBz, "staking derivates - DRV", nil, nil) require.NoError(t, err) require.NotEmpty(t, stakingAddr) diff --git a/x/compute/internal/keeper/test_common.go b/x/compute/internal/keeper/test_common.go index 508b729cd..6aa0041f4 100644 --- a/x/compute/internal/keeper/test_common.go +++ b/x/compute/internal/keeper/test_common.go @@ -542,7 +542,7 @@ func TestHandler(k Keeper) sdk.Handler { } func handleInstantiate(ctx sdk.Context, k Keeper, msg *wasmtypes.MsgInstantiateContract) (*sdk.Result, error) { - contractAddr, data, err := k.Instantiate(ctx, msg.CodeID, msg.Sender, msg.InitMsg, msg.Label, msg.InitFunds, msg.CallbackSig) + contractAddr, data, err := k.Instantiate(ctx, msg.CodeID, msg.Sender, nil, msg.InitMsg, msg.Label, msg.InitFunds, msg.CallbackSig) if err != nil { result := sdk.Result{} result.Data = data diff --git a/x/compute/internal/types/events.go b/x/compute/internal/types/events.go index 17ce47c8f..2315ac4c4 100644 --- a/x/compute/internal/types/events.go +++ b/x/compute/internal/types/events.go @@ -6,24 +6,23 @@ const ( // CustomContractEventPrefix contracts can create custom events. To not mix them with other system events they got the `wasm-` prefix. CustomContractEventPrefix = "wasm-" - EventTypeStoreCode = "store_code" - EventTypeInstantiate = "instantiate" - EventTypeExecute = "execute" - EventTypeMigrate = "migrate" - EventTypePinCode = "pin_code" - EventTypeUnpinCode = "unpin_code" - EventTypeSudo = "sudo" - EventTypeReply = "reply" - EventTypeGovContractResult = "gov_contract_result" + EventTypeStoreCode = "store_code" + EventTypeInstantiate = "instantiate" + EventTypeExecute = "execute" + EventTypeMigrate = "migrate" + EventTypePinCode = "pin_code" + EventTypeUnpinCode = "unpin_code" + EventTypeSudo = "sudo" + EventTypeReply = "reply" + EventTypeUpdateContractAdmin = "update_contract_admin" ) // event attributes returned from contract execution const ( AttributeReservedPrefix = "_" - AttributeKeyContractAddr = "contract_address" - AttributeKeyCodeID = "code_id" - AttributeKeySigner = "signer" - AttributeKeyResultDataHex = "result" - AttributeKeyFeature = "feature" + AttributeKeyContractAddr = "contract_address" + AttributeKeyCodeID = "code_id" + AttributeKeySigner = "signer" + AttributeKeyNewAdmin = "new_admin_address" ) diff --git a/x/compute/internal/types/msg.go b/x/compute/internal/types/msg.go index 5d7b8fcc4..f5e826172 100644 --- a/x/compute/internal/types/msg.go +++ b/x/compute/internal/types/msg.go @@ -1,6 +1,8 @@ package types import ( + "strings" + sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) @@ -107,3 +109,108 @@ func (msg MsgExecuteContract) GetSignBytes() []byte { func (msg MsgExecuteContract) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{msg.Sender} } + +func (msg MsgMigrateContract) Route() string { + return RouterKey +} + +func (msg MsgMigrateContract) Type() string { + return "migrate" +} + +func (msg MsgMigrateContract) ValidateBasic() error { + if msg.CodeID == 0 { + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "code id is required") + } + if _, err := sdk.AccAddressFromBech32(msg.Sender); err != nil { + return sdkerrors.Wrap(err, "sender") + } + if _, err := sdk.AccAddressFromBech32(msg.Contract); err != nil { + return sdkerrors.Wrap(err, "contract") + } + + return nil +} + +func (msg MsgMigrateContract) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&msg)) +} + +func (msg MsgMigrateContract) GetSigners() []sdk.AccAddress { + senderAddr, err := sdk.AccAddressFromBech32(msg.Sender) + if err != nil { // should never happen as valid basic rejects invalid addresses + panic(err.Error()) + } + return []sdk.AccAddress{senderAddr} +} + +// GetFunds returns tokens send to the contract +func (msg MsgMigrateContract) GetFunds() sdk.Coins { + return sdk.NewCoins() +} + +func (msg MsgUpdateAdmin) Route() string { + return RouterKey +} + +func (msg MsgUpdateAdmin) Type() string { + return "update-contract-admin" +} + +func (msg MsgUpdateAdmin) ValidateBasic() error { + if _, err := sdk.AccAddressFromBech32(msg.Sender); err != nil { + return sdkerrors.Wrap(err, "sender") + } + if _, err := sdk.AccAddressFromBech32(msg.Contract); err != nil { + return sdkerrors.Wrap(err, "contract") + } + if _, err := sdk.AccAddressFromBech32(msg.NewAdmin); err != nil { + return sdkerrors.Wrap(err, "new admin") + } + if strings.EqualFold(msg.Sender, msg.NewAdmin) { + return sdkerrors.Wrap(ErrInvalidMsg, "new admin is the same as the old") + } + return nil +} + +func (msg MsgUpdateAdmin) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&msg)) +} + +func (msg MsgUpdateAdmin) GetSigners() []sdk.AccAddress { + senderAddr, err := sdk.AccAddressFromBech32(msg.Sender) + if err != nil { // should never happen as valid basic rejects invalid addresses + panic(err.Error()) + } + return []sdk.AccAddress{senderAddr} +} + +func (msg MsgClearAdmin) Route() string { + return RouterKey +} + +func (msg MsgClearAdmin) Type() string { + return "clear-contract-admin" +} + +func (msg MsgClearAdmin) ValidateBasic() error { + if _, err := sdk.AccAddressFromBech32(msg.Sender); err != nil { + return sdkerrors.Wrap(err, "sender") + } + if _, err := sdk.AccAddressFromBech32(msg.Contract); err != nil { + return sdkerrors.Wrap(err, "contract") + } + return nil +} + +func (msg MsgClearAdmin) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&msg)) +} + +func (msg MsgClearAdmin) GetSigners() []sdk.AccAddress { + senderAddr, err := sdk.AccAddressFromBech32(msg.Sender) + if err != nil { // should never happen as valid basic rejects invalid addresses + panic(err.Error()) + } + return []sdk.AccAddress{senderAddr} +} diff --git a/x/compute/internal/types/types.go b/x/compute/internal/types/types.go index 0922206d6..a433c20e1 100644 --- a/x/compute/internal/types/types.go +++ b/x/compute/internal/types/types.go @@ -289,3 +289,28 @@ contract-memory-cache-size = "{{ .WASMConfig.CacheSize }}" # The WASM VM memory cache size in number of cached modules. Can safely go up to 15, but not recommended for validators contract-memory-enclave-cache-size = "{{ .WASMConfig.EnclaveCacheSize }}" ` + +func (c ContractInfo) InitialHistory(initMsg []byte) ContractCodeHistoryEntry { + return ContractCodeHistoryEntry{ + Operation: ContractCodeHistoryOperationTypeInit, + CodeID: c.CodeID, + Updated: c.Created, + Msg: initMsg, + } +} + +func (c *ContractInfo) AddMigration(ctx sdk.Context, codeID uint64, msg []byte) ContractCodeHistoryEntry { + h := ContractCodeHistoryEntry{ + Operation: ContractCodeHistoryOperationTypeMigrate, + CodeID: codeID, + Updated: NewAbsoluteTxPosition(ctx), + Msg: msg, + } + c.CodeID = codeID + return h +} + +// AdminAddr convert into sdk.AccAddress or nil when not set +func (c *ContractInfo) AdminAddr() sdk.AccAddress { + return c.Admin +} diff --git a/x/compute/internal/types/types.pb.go b/x/compute/internal/types/types.pb.go index bda1cf381..150c4bd8b 100644 --- a/x/compute/internal/types/types.pb.go +++ b/x/compute/internal/types/types.pb.go @@ -53,6 +53,42 @@ func (AccessType) EnumDescriptor() ([]byte, []int) { return fileDescriptor_8ba7f40a6d1951b3, []int{0} } +// ContractCodeHistoryOperationType actions that caused a code change +type ContractCodeHistoryOperationType int32 + +const ( + // ContractCodeHistoryOperationTypeUnspecified placeholder for empty value + ContractCodeHistoryOperationTypeUnspecified ContractCodeHistoryOperationType = 0 + // ContractCodeHistoryOperationTypeInit on chain contract instantiation + ContractCodeHistoryOperationTypeInit ContractCodeHistoryOperationType = 1 + // ContractCodeHistoryOperationTypeMigrate code migration + ContractCodeHistoryOperationTypeMigrate ContractCodeHistoryOperationType = 2 + // ContractCodeHistoryOperationTypeGenesis based on genesis data + ContractCodeHistoryOperationTypeGenesis ContractCodeHistoryOperationType = 3 +) + +var ContractCodeHistoryOperationType_name = map[int32]string{ + 0: "CONTRACT_CODE_HISTORY_OPERATION_TYPE_UNSPECIFIED", + 1: "CONTRACT_CODE_HISTORY_OPERATION_TYPE_INIT", + 2: "CONTRACT_CODE_HISTORY_OPERATION_TYPE_MIGRATE", + 3: "CONTRACT_CODE_HISTORY_OPERATION_TYPE_GENESIS", +} + +var ContractCodeHistoryOperationType_value = map[string]int32{ + "CONTRACT_CODE_HISTORY_OPERATION_TYPE_UNSPECIFIED": 0, + "CONTRACT_CODE_HISTORY_OPERATION_TYPE_INIT": 1, + "CONTRACT_CODE_HISTORY_OPERATION_TYPE_MIGRATE": 2, + "CONTRACT_CODE_HISTORY_OPERATION_TYPE_GENESIS": 3, +} + +func (x ContractCodeHistoryOperationType) String() string { + return proto.EnumName(ContractCodeHistoryOperationType_name, int32(x)) +} + +func (ContractCodeHistoryOperationType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_8ba7f40a6d1951b3, []int{1} +} + type AccessTypeParam struct { Value AccessType `protobuf:"varint,1,opt,name=value,proto3,enum=secret.compute.v1beta1.AccessType" json:"value,omitempty" yaml:"value"` } @@ -299,14 +335,59 @@ func (m *Model) XXX_DiscardUnknown() { var xxx_messageInfo_Model proto.InternalMessageInfo +// ContractCodeHistoryEntry metadata to a contract. +type ContractCodeHistoryEntry struct { + Operation ContractCodeHistoryOperationType `protobuf:"varint,1,opt,name=operation,proto3,enum=secret.compute.v1beta1.ContractCodeHistoryOperationType" json:"operation,omitempty"` + // CodeID is the reference to the stored WASM code + CodeID uint64 `protobuf:"varint,2,opt,name=code_id,json=codeId,proto3" json:"code_id,omitempty"` + // Updated Tx position when the operation was executed. + Updated *AbsoluteTxPosition `protobuf:"bytes,3,opt,name=updated,proto3" json:"updated,omitempty"` + Msg []byte `protobuf:"bytes,4,opt,name=msg,proto3" json:"msg,omitempty"` +} + +func (m *ContractCodeHistoryEntry) Reset() { *m = ContractCodeHistoryEntry{} } +func (m *ContractCodeHistoryEntry) String() string { return proto.CompactTextString(m) } +func (*ContractCodeHistoryEntry) ProtoMessage() {} +func (*ContractCodeHistoryEntry) Descriptor() ([]byte, []int) { + return fileDescriptor_8ba7f40a6d1951b3, []int{6} +} +func (m *ContractCodeHistoryEntry) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ContractCodeHistoryEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ContractCodeHistoryEntry.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ContractCodeHistoryEntry) XXX_Merge(src proto.Message) { + xxx_messageInfo_ContractCodeHistoryEntry.Merge(m, src) +} +func (m *ContractCodeHistoryEntry) XXX_Size() int { + return m.Size() +} +func (m *ContractCodeHistoryEntry) XXX_DiscardUnknown() { + xxx_messageInfo_ContractCodeHistoryEntry.DiscardUnknown(m) +} + +var xxx_messageInfo_ContractCodeHistoryEntry proto.InternalMessageInfo + func init() { proto.RegisterEnum("secret.compute.v1beta1.AccessType", AccessType_name, AccessType_value) + proto.RegisterEnum("secret.compute.v1beta1.ContractCodeHistoryOperationType", ContractCodeHistoryOperationType_name, ContractCodeHistoryOperationType_value) proto.RegisterType((*AccessTypeParam)(nil), "secret.compute.v1beta1.AccessTypeParam") proto.RegisterType((*CodeInfo)(nil), "secret.compute.v1beta1.CodeInfo") proto.RegisterType((*ContractCustomInfo)(nil), "secret.compute.v1beta1.ContractCustomInfo") proto.RegisterType((*ContractInfo)(nil), "secret.compute.v1beta1.ContractInfo") proto.RegisterType((*AbsoluteTxPosition)(nil), "secret.compute.v1beta1.AbsoluteTxPosition") proto.RegisterType((*Model)(nil), "secret.compute.v1beta1.Model") + proto.RegisterType((*ContractCodeHistoryEntry)(nil), "secret.compute.v1beta1.ContractCodeHistoryEntry") } func init() { @@ -314,55 +395,68 @@ func init() { } var fileDescriptor_8ba7f40a6d1951b3 = []byte{ - // 759 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0x4d, 0x6f, 0xe3, 0x44, - 0x18, 0x8e, 0x9b, 0xaf, 0x66, 0x1a, 0x96, 0x68, 0x28, 0x4b, 0x36, 0x48, 0x4e, 0x30, 0x12, 0xaa, - 0x16, 0x35, 0x56, 0x17, 0x0e, 0xa8, 0xb7, 0xba, 0x0e, 0x34, 0x5b, 0x48, 0xab, 0xe9, 0xee, 0x4a, - 0x05, 0xa4, 0xc8, 0x9e, 0x79, 0xb7, 0xb1, 0xe2, 0x78, 0xa2, 0x99, 0x49, 0x88, 0xff, 0x01, 0xea, - 0x89, 0x23, 0x97, 0x4a, 0x48, 0x20, 0xb4, 0x7f, 0x80, 0xff, 0xb0, 0xc7, 0x3d, 0x70, 0xe0, 0x14, - 0x41, 0xfa, 0x0f, 0x38, 0xf6, 0x84, 0x3c, 0x76, 0x3e, 0xc4, 0xc7, 0x05, 0xed, 0xc9, 0xef, 0xe7, - 0xf3, 0x3e, 0xef, 0xf3, 0xda, 0x46, 0x96, 0x04, 0x2a, 0x40, 0xd9, 0x94, 0x8f, 0xc6, 0x13, 0x05, - 0xf6, 0xf4, 0xc0, 0x07, 0xe5, 0x1d, 0xd8, 0x2a, 0x1e, 0x83, 0x6c, 0x8f, 0x05, 0x57, 0x1c, 0xdf, - 0x4f, 0x6b, 0xda, 0x59, 0x4d, 0x3b, 0xab, 0x69, 0xec, 0x5e, 0xf1, 0x2b, 0xae, 0x4b, 0xec, 0xc4, - 0x4a, 0xab, 0x2d, 0x8a, 0xde, 0x3c, 0xa2, 0x14, 0xa4, 0x7c, 0x12, 0x8f, 0xe1, 0xdc, 0x13, 0xde, - 0x08, 0x3f, 0x46, 0xc5, 0xa9, 0x17, 0x4e, 0xa0, 0x6e, 0xb4, 0x8c, 0xbd, 0x7b, 0x8f, 0xac, 0xf6, - 0xbf, 0x03, 0xb6, 0xd7, 0x7d, 0x4e, 0xed, 0xcf, 0x79, 0xb3, 0x1a, 0x7b, 0xa3, 0xf0, 0xd0, 0xd2, - 0xad, 0x16, 0x49, 0x21, 0x0e, 0x0b, 0xdf, 0xff, 0xd0, 0x34, 0xac, 0x9f, 0x0d, 0xb4, 0x7d, 0xcc, - 0x19, 0x74, 0xa3, 0xe7, 0x1c, 0xbf, 0x8b, 0x2a, 0x94, 0x33, 0xe8, 0x0f, 0x3c, 0x39, 0xd0, 0x23, - 0xaa, 0x64, 0x3b, 0x09, 0x9c, 0x78, 0x72, 0x80, 0x4f, 0x51, 0x99, 0x0a, 0xf0, 0x14, 0x17, 0xf5, - 0xad, 0x24, 0xe5, 0x1c, 0xdc, 0xcd, 0x9b, 0xfb, 0x57, 0x81, 0x1a, 0x4c, 0xfc, 0x84, 0x80, 0x4d, - 0xb9, 0x1c, 0x71, 0x99, 0x3d, 0xf6, 0x25, 0x1b, 0x66, 0xbb, 0x1f, 0x51, 0x7a, 0xc4, 0x98, 0x00, - 0x29, 0xc9, 0x12, 0x01, 0xdf, 0x47, 0x25, 0xc9, 0x27, 0x82, 0x42, 0x3d, 0xdf, 0x32, 0xf6, 0x2a, - 0x24, 0xf3, 0x70, 0x1d, 0x95, 0xfd, 0x49, 0x10, 0x32, 0x10, 0xf5, 0x82, 0x4e, 0x2c, 0x5d, 0xeb, - 0x2b, 0x84, 0x8f, 0x79, 0xa4, 0x84, 0x47, 0xd5, 0xf1, 0x44, 0x2a, 0x3e, 0xd2, 0x8c, 0x6d, 0xb4, - 0x03, 0x11, 0x0d, 0xbd, 0x29, 0xf4, 0x87, 0x10, 0xa7, 0x9c, 0x9d, 0x7b, 0x8b, 0x79, 0x13, 0x75, - 0xd2, 0xf0, 0x29, 0xc4, 0x04, 0xc1, 0xca, 0xc6, 0xbb, 0xa8, 0x18, 0x7a, 0x3e, 0x84, 0x7a, 0x87, - 0x0a, 0x49, 0x1d, 0xeb, 0xd7, 0x2d, 0x54, 0x5d, 0xa2, 0x6b, 0xdc, 0xf7, 0x51, 0x59, 0x2b, 0x11, - 0x30, 0x8d, 0x59, 0x70, 0xd0, 0x62, 0xde, 0x2c, 0x69, 0xa1, 0x5c, 0x52, 0x4a, 0x52, 0x5d, 0xf6, - 0x7a, 0x15, 0x59, 0x11, 0x2b, 0x6c, 0x10, 0xc3, 0x6e, 0x36, 0x02, 0x58, 0xbd, 0xd8, 0x32, 0xf6, - 0x76, 0x1e, 0x3d, 0xfc, 0xcf, 0x93, 0xfb, 0x92, 0x87, 0x13, 0x05, 0x4f, 0x66, 0xe7, 0x5c, 0x06, - 0x2a, 0xe0, 0x11, 0x59, 0xb6, 0xe2, 0x7d, 0xb4, 0x13, 0xf8, 0xb4, 0x3f, 0xe6, 0x42, 0x25, 0x1b, - 0x95, 0x92, 0x09, 0xce, 0x1b, 0x8b, 0x79, 0xb3, 0xd2, 0x75, 0x8e, 0xcf, 0xb9, 0x50, 0x5d, 0x97, - 0x54, 0x02, 0x9f, 0x6a, 0x93, 0xe1, 0xcf, 0x50, 0xd1, 0x63, 0xa3, 0x20, 0xaa, 0x97, 0xff, 0xef, - 0x56, 0x69, 0xbf, 0x45, 0x10, 0xfe, 0x27, 0x2d, 0xfc, 0x1e, 0xaa, 0xfa, 0x21, 0xa7, 0xc3, 0xfe, - 0x00, 0x82, 0xab, 0x81, 0xd2, 0x02, 0xe7, 0xc9, 0x8e, 0x8e, 0x9d, 0xe8, 0x10, 0x7e, 0x80, 0xb6, - 0xd5, 0xac, 0x1f, 0x44, 0x0c, 0x66, 0x5a, 0xda, 0x02, 0x29, 0xab, 0x59, 0x37, 0x71, 0xad, 0x00, - 0x15, 0xbf, 0xe0, 0x0c, 0x42, 0xfc, 0x18, 0xe5, 0x4f, 0x57, 0x27, 0xff, 0xe4, 0x6e, 0xde, 0xfc, - 0x78, 0x83, 0xa3, 0x82, 0x88, 0x81, 0x18, 0x05, 0x91, 0xda, 0x34, 0xc3, 0xc0, 0x97, 0xb6, 0x1f, - 0x2b, 0x90, 0xed, 0x13, 0x98, 0x39, 0x89, 0x41, 0xf2, 0xd9, 0x5b, 0xf1, 0x4c, 0x7f, 0x57, 0xfa, - 0x8e, 0x24, 0x75, 0x1e, 0xfe, 0x62, 0x20, 0xb4, 0xfe, 0x92, 0xf0, 0x07, 0xa8, 0xf2, 0xb4, 0xe7, - 0x76, 0x3e, 0xed, 0xf6, 0x3a, 0x6e, 0x2d, 0xd7, 0x78, 0xe7, 0xfa, 0xa6, 0xf5, 0xd6, 0x3a, 0xfd, - 0x34, 0x62, 0xf0, 0x3c, 0x88, 0x80, 0xe1, 0x16, 0x2a, 0xf5, 0xce, 0x9c, 0x33, 0xf7, 0xb2, 0x66, - 0x34, 0x76, 0xaf, 0x6f, 0x5a, 0xb5, 0x75, 0x51, 0x8f, 0xfb, 0x9c, 0xc5, 0xf8, 0x43, 0x54, 0x3d, - 0xeb, 0x7d, 0x7e, 0xd9, 0x3f, 0x72, 0x5d, 0xd2, 0xb9, 0xb8, 0xa8, 0x6d, 0x35, 0x1e, 0x5c, 0xdf, - 0xb4, 0xde, 0x5e, 0xd7, 0x9d, 0x45, 0x61, 0x9c, 0x69, 0x99, 0x8c, 0xed, 0x3c, 0xeb, 0x90, 0x4b, - 0x8d, 0x98, 0xff, 0xfb, 0xd8, 0xce, 0x14, 0x44, 0x9c, 0x80, 0x36, 0xb6, 0xbf, 0xfd, 0xd1, 0xcc, - 0xbd, 0xf8, 0xc9, 0xcc, 0x39, 0x5f, 0xbf, 0xfc, 0xc3, 0xcc, 0xbd, 0x58, 0x98, 0xc6, 0xcb, 0x85, - 0x69, 0xbc, 0x5a, 0x98, 0xc6, 0xef, 0x0b, 0xd3, 0xf8, 0xee, 0xd6, 0xcc, 0xbd, 0xba, 0x35, 0x73, - 0xbf, 0xdd, 0x9a, 0xb9, 0x2f, 0x0f, 0x37, 0xa4, 0x92, 0x54, 0xa8, 0xd0, 0xf3, 0xa5, 0x7d, 0xa1, - 0x5f, 0xac, 0x1e, 0xa8, 0x6f, 0xb8, 0x18, 0xda, 0xb3, 0xd5, 0x9f, 0x2c, 0x88, 0x14, 0x88, 0xc8, - 0x0b, 0xd3, 0x33, 0xfb, 0x25, 0xfd, 0x77, 0xfa, 0xe8, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xed, - 0xe3, 0x3f, 0x30, 0xf1, 0x04, 0x00, 0x00, + // 974 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0xcd, 0x6e, 0x23, 0x45, + 0x10, 0xf6, 0xc4, 0x8e, 0x1d, 0x77, 0xcc, 0x62, 0x35, 0x61, 0xf1, 0x1a, 0xc9, 0x1e, 0x06, 0x04, + 0x21, 0x21, 0x36, 0x59, 0x38, 0xac, 0x72, 0xf3, 0xcf, 0x6c, 0x32, 0x1b, 0x32, 0xb6, 0xda, 0x4e, + 0x50, 0xf8, 0xd1, 0x68, 0x7e, 0x2a, 0xf6, 0x28, 0xe3, 0x69, 0x6b, 0xba, 0x1d, 0x3c, 0x6f, 0x80, + 0x7c, 0xe2, 0xc8, 0xc5, 0x12, 0x12, 0x68, 0xb5, 0x2f, 0xc0, 0x3b, 0xec, 0x71, 0x0f, 0x1c, 0x38, + 0x59, 0xe0, 0x3c, 0x00, 0x12, 0xc7, 0x3d, 0xa1, 0x69, 0x3b, 0xb1, 0x05, 0x1b, 0x25, 0x20, 0x4e, + 0x53, 0xd5, 0x5d, 0xf5, 0xd5, 0xdf, 0x57, 0xd3, 0x48, 0x61, 0x60, 0x07, 0xc0, 0xcb, 0x36, 0xed, + 0xf5, 0x07, 0x1c, 0xca, 0x17, 0xbb, 0x16, 0x70, 0x73, 0xb7, 0xcc, 0xc3, 0x3e, 0xb0, 0x52, 0x3f, + 0xa0, 0x9c, 0xe2, 0xfb, 0x33, 0x9b, 0xd2, 0xdc, 0xa6, 0x34, 0xb7, 0xc9, 0x6f, 0x74, 0x68, 0x87, + 0x0a, 0x93, 0x72, 0x24, 0xcd, 0xac, 0x15, 0x1b, 0xbd, 0x5e, 0xb1, 0x6d, 0x60, 0xac, 0x1d, 0xf6, + 0xa1, 0x69, 0x06, 0x66, 0x0f, 0x3f, 0x41, 0xab, 0x17, 0xa6, 0x37, 0x80, 0x9c, 0x24, 0x4b, 0x9b, + 0xf7, 0x1e, 0x2a, 0xa5, 0x57, 0x03, 0x96, 0x16, 0x7e, 0xd5, 0xec, 0x9f, 0x93, 0x62, 0x26, 0x34, + 0x7b, 0xde, 0x9e, 0x22, 0x5c, 0x15, 0x32, 0x83, 0xd8, 0x4b, 0x7c, 0xff, 0x43, 0x51, 0x52, 0x9e, + 0x4a, 0x68, 0xad, 0x46, 0x1d, 0xd0, 0xfc, 0x33, 0x8a, 0xdf, 0x46, 0x69, 0x9b, 0x3a, 0x60, 0x74, + 0x4d, 0xd6, 0x15, 0x21, 0x32, 0x64, 0x2d, 0x3a, 0x38, 0x30, 0x59, 0x17, 0x1f, 0xa2, 0x94, 0x1d, + 0x80, 0xc9, 0x69, 0x90, 0x5b, 0x89, 0xae, 0xaa, 0xbb, 0x2f, 0x27, 0xc5, 0x9d, 0x8e, 0xcb, 0xbb, + 0x03, 0x2b, 0x4a, 0xa0, 0x6c, 0x53, 0xd6, 0xa3, 0x6c, 0xfe, 0xd9, 0x61, 0xce, 0xf9, 0xbc, 0xf6, + 0x8a, 0x6d, 0x57, 0x1c, 0x27, 0x00, 0xc6, 0xc8, 0x15, 0x02, 0xbe, 0x8f, 0x92, 0x8c, 0x0e, 0x02, + 0x1b, 0x72, 0x71, 0x59, 0xda, 0x4c, 0x93, 0xb9, 0x86, 0x73, 0x28, 0x65, 0x0d, 0x5c, 0xcf, 0x81, + 0x20, 0x97, 0x10, 0x17, 0x57, 0xaa, 0xf2, 0x25, 0xc2, 0x35, 0xea, 0xf3, 0xc0, 0xb4, 0x79, 0x6d, + 0xc0, 0x38, 0xed, 0x89, 0x8c, 0xcb, 0x68, 0x1d, 0x7c, 0xdb, 0x33, 0x2f, 0xc0, 0x38, 0x87, 0x70, + 0x96, 0x73, 0xf5, 0xde, 0x74, 0x52, 0x44, 0xea, 0xec, 0xf8, 0x10, 0x42, 0x82, 0xe0, 0x5a, 0xc6, + 0x1b, 0x68, 0xd5, 0x33, 0x2d, 0xf0, 0x44, 0x0d, 0x69, 0x32, 0x53, 0x94, 0x5f, 0x56, 0x50, 0xe6, + 0x0a, 0x5d, 0xe0, 0xbe, 0x8b, 0x52, 0xa2, 0x13, 0xae, 0x23, 0x30, 0x13, 0x55, 0x34, 0x9d, 0x14, + 0x93, 0xa2, 0x51, 0x75, 0x92, 0x8c, 0xae, 0x34, 0xe7, 0xff, 0xed, 0xc8, 0x75, 0x62, 0x89, 0xa5, + 0xc4, 0x70, 0x7d, 0x1e, 0x02, 0x9c, 0xdc, 0xaa, 0x2c, 0x6d, 0xae, 0x3f, 0xdc, 0xba, 0x71, 0xe4, + 0x16, 0xa3, 0xde, 0x80, 0x43, 0x7b, 0xd8, 0xa4, 0xcc, 0xe5, 0x2e, 0xf5, 0xc9, 0x95, 0x2b, 0xde, + 0x41, 0xeb, 0xae, 0x65, 0x1b, 0x7d, 0x1a, 0xf0, 0xa8, 0xa2, 0x64, 0x14, 0xa1, 0xfa, 0xda, 0x74, + 0x52, 0x4c, 0x6b, 0xd5, 0x5a, 0x93, 0x06, 0x5c, 0xab, 0x93, 0xb4, 0x6b, 0xd9, 0x42, 0x74, 0xf0, + 0x3e, 0x5a, 0x35, 0x9d, 0x9e, 0xeb, 0xe7, 0x52, 0xff, 0xb5, 0xaa, 0x99, 0xbf, 0x42, 0x10, 0xfe, + 0x67, 0x5a, 0xf8, 0x1d, 0x94, 0xb1, 0x3c, 0x6a, 0x9f, 0x1b, 0x5d, 0x70, 0x3b, 0x5d, 0x2e, 0x1a, + 0x1c, 0x27, 0xeb, 0xe2, 0xec, 0x40, 0x1c, 0xe1, 0x07, 0x68, 0x8d, 0x0f, 0x0d, 0xd7, 0x77, 0x60, + 0x28, 0x5a, 0x9b, 0x20, 0x29, 0x3e, 0xd4, 0x22, 0x55, 0x71, 0xd1, 0xea, 0x11, 0x75, 0xc0, 0xc3, + 0x4f, 0x50, 0xfc, 0xf0, 0x7a, 0xe4, 0x8f, 0x5e, 0x4e, 0x8a, 0x9f, 0x2e, 0xe5, 0xc8, 0xc1, 0x77, + 0x20, 0xe8, 0xb9, 0x3e, 0x5f, 0x16, 0x3d, 0xd7, 0x62, 0x65, 0x2b, 0xe4, 0xc0, 0x4a, 0x07, 0x30, + 0xac, 0x46, 0x02, 0x89, 0xcf, 0x59, 0x71, 0x22, 0xf6, 0x4a, 0xcc, 0x91, 0xcc, 0x14, 0xe5, 0x0f, + 0x09, 0xe5, 0xae, 0x39, 0x17, 0xad, 0x81, 0xcb, 0x38, 0x0d, 0x42, 0xd5, 0xe7, 0x41, 0x88, 0x4f, + 0x50, 0x9a, 0xf6, 0x21, 0x30, 0xa3, 0x92, 0xe6, 0xeb, 0xf8, 0xe8, 0xa6, 0xd9, 0xbc, 0x02, 0xa4, + 0x71, 0xe5, 0x1b, 0x2d, 0x29, 0x59, 0x40, 0x2d, 0x33, 0x6f, 0xe5, 0x46, 0xe6, 0xd5, 0x51, 0x6a, + 0xd0, 0x77, 0x04, 0x2d, 0xe2, 0xff, 0x9e, 0x16, 0x73, 0x57, 0x9c, 0x45, 0xf1, 0x1e, 0xeb, 0x08, + 0xc2, 0x65, 0x48, 0x24, 0x6e, 0xfd, 0x2c, 0x21, 0xb4, 0xf8, 0x77, 0xe0, 0xf7, 0x51, 0xfa, 0x58, + 0xaf, 0xab, 0x8f, 0x35, 0x5d, 0xad, 0x67, 0x63, 0xf9, 0xb7, 0x46, 0x63, 0xf9, 0x8d, 0xc5, 0xf5, + 0xb1, 0xef, 0xc0, 0x99, 0xeb, 0x83, 0x83, 0x65, 0x94, 0xd4, 0x1b, 0xd5, 0x46, 0xfd, 0x34, 0x2b, + 0xe5, 0x37, 0x46, 0x63, 0x39, 0xbb, 0x30, 0xd2, 0xa9, 0x45, 0x9d, 0x10, 0x6f, 0xa3, 0x4c, 0x43, + 0xff, 0xec, 0xd4, 0xa8, 0xd4, 0xeb, 0x44, 0x6d, 0xb5, 0xb2, 0x2b, 0xf9, 0x07, 0xa3, 0xb1, 0xfc, + 0xe6, 0xc2, 0xae, 0xe1, 0x7b, 0xe1, 0x9c, 0x3d, 0x51, 0x58, 0xf5, 0x44, 0x25, 0xa7, 0x02, 0x31, + 0xfe, 0xf7, 0xb0, 0xea, 0x05, 0x04, 0x61, 0x04, 0x9a, 0x5f, 0xfb, 0xf6, 0xc7, 0x42, 0xec, 0xd9, + 0x4f, 0x85, 0xd8, 0xd6, 0xd3, 0x38, 0x92, 0x6f, 0x6b, 0x32, 0x06, 0xf4, 0x71, 0xad, 0xa1, 0xb7, + 0x49, 0xa5, 0xd6, 0x36, 0x6a, 0x8d, 0xba, 0x6a, 0x1c, 0x68, 0xad, 0x76, 0x83, 0x9c, 0x1a, 0x8d, + 0xa6, 0x4a, 0x2a, 0x6d, 0xad, 0xa1, 0x1b, 0xed, 0xd3, 0xa6, 0x6a, 0x1c, 0xeb, 0xad, 0xa6, 0x5a, + 0xd3, 0x1e, 0x6b, 0xa2, 0xe8, 0xf2, 0x68, 0x2c, 0x6f, 0xdf, 0x86, 0x7d, 0xec, 0xb3, 0x3e, 0xd8, + 0xee, 0x99, 0x0b, 0x0e, 0xfe, 0x1c, 0x7d, 0x78, 0xa7, 0x30, 0x9a, 0xae, 0xb5, 0xb3, 0x52, 0x7e, + 0x73, 0x34, 0x96, 0xdf, 0xbb, 0x0d, 0x5f, 0xf3, 0x5d, 0x8e, 0xbf, 0x46, 0x1f, 0xdd, 0x09, 0xf8, + 0x48, 0xdb, 0x27, 0x95, 0xb6, 0x9a, 0x5d, 0xc9, 0x6f, 0x8f, 0xc6, 0xf2, 0x07, 0xb7, 0x61, 0x1f, + 0xb9, 0x9d, 0xc0, 0xe4, 0x70, 0x67, 0xf8, 0x7d, 0x55, 0x57, 0x5b, 0x5a, 0x2b, 0x1b, 0xbf, 0x1b, + 0xfc, 0x3e, 0xf8, 0xc0, 0x5c, 0x96, 0x4f, 0x44, 0xc3, 0xaa, 0x7e, 0xf5, 0xfc, 0xf7, 0x42, 0xec, + 0xd9, 0xb4, 0x20, 0x3d, 0x9f, 0x16, 0xa4, 0x17, 0xd3, 0x82, 0xf4, 0xdb, 0xb4, 0x20, 0x7d, 0x77, + 0x59, 0x88, 0xbd, 0xb8, 0x2c, 0xc4, 0x7e, 0xbd, 0x2c, 0xc4, 0xbe, 0xd8, 0x5b, 0xda, 0x62, 0x66, + 0x07, 0xdc, 0x33, 0x2d, 0x56, 0x6e, 0x09, 0x72, 0xeb, 0xc0, 0xbf, 0xa1, 0xc1, 0x79, 0x79, 0x78, + 0xfd, 0xc8, 0xba, 0x3e, 0x87, 0xc0, 0x37, 0xbd, 0xd9, 0x1f, 0xc8, 0x4a, 0x8a, 0x87, 0xf3, 0x93, + 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0xe8, 0xb4, 0x45, 0xcb, 0x8c, 0x07, 0x00, 0x00, } func (this *AccessTypeParam) Equal(that interface{}) bool { @@ -542,6 +636,39 @@ func (this *Model) Equal(that interface{}) bool { } return true } +func (this *ContractCodeHistoryEntry) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*ContractCodeHistoryEntry) + if !ok { + that2, ok := that.(ContractCodeHistoryEntry) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.Operation != that1.Operation { + return false + } + if this.CodeID != that1.CodeID { + return false + } + if !this.Updated.Equal(that1.Updated) { + return false + } + if !bytes.Equal(this.Msg, that1.Msg) { + return false + } + return true +} func (m *AccessTypeParam) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -796,6 +923,58 @@ func (m *Model) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *ContractCodeHistoryEntry) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ContractCodeHistoryEntry) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ContractCodeHistoryEntry) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Msg) > 0 { + i -= len(m.Msg) + copy(dAtA[i:], m.Msg) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Msg))) + i-- + dAtA[i] = 0x22 + } + if m.Updated != nil { + { + size, err := m.Updated.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if m.CodeID != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.CodeID)) + i-- + dAtA[i] = 0x10 + } + if m.Operation != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.Operation)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func encodeVarintTypes(dAtA []byte, offset int, v uint64) int { offset -= sovTypes(v) base := offset @@ -925,6 +1104,29 @@ func (m *Model) Size() (n int) { return n } +func (m *ContractCodeHistoryEntry) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Operation != 0 { + n += 1 + sovTypes(uint64(m.Operation)) + } + if m.CodeID != 0 { + n += 1 + sovTypes(uint64(m.CodeID)) + } + if m.Updated != nil { + l = m.Updated.Size() + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.Msg) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + return n +} + func sovTypes(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -1741,6 +1943,164 @@ func (m *Model) Unmarshal(dAtA []byte) error { } return nil } +func (m *ContractCodeHistoryEntry) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ContractCodeHistoryEntry: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ContractCodeHistoryEntry: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Operation", wireType) + } + m.Operation = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Operation |= ContractCodeHistoryOperationType(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CodeID", wireType) + } + m.CodeID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CodeID |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Updated", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Updated == nil { + m.Updated = &AbsoluteTxPosition{} + } + if err := m.Updated.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Msg", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Msg = append(m.Msg[:0], dAtA[iNdEx:postIndex]...) + if m.Msg == nil { + m.Msg = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipTypes(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 From e3f8dffb635c191e961fd4bffc1857bd8aab6b9c Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 8 Feb 2023 13:24:07 +0200 Subject: [PATCH 004/164] checkpoint --- go-cosmwasm/lib.go | 117 ++++++++++++++++++++++++++++ go-cosmwasm/types/types.go | 1 + x/compute/internal/keeper/keeper.go | 79 +++++++++++++++++++ x/compute/internal/types/types.go | 4 +- 4 files changed, 199 insertions(+), 2 deletions(-) diff --git a/go-cosmwasm/lib.go b/go-cosmwasm/lib.go index 916354fff..67d86dd11 100644 --- a/go-cosmwasm/lib.go +++ b/go-cosmwasm/lib.go @@ -396,3 +396,120 @@ func (w *Wasmer) AnalyzeCode( ) (*v1types.AnalysisReport, error) { return api.AnalyzeCode(w.cache, codeHash) } + +// Migrate will migrate an existing contract to a new code binary. +// This takes storage of the data from the original contract and the CodeID of the new contract that should +// replace it. This allows it to run a migration step if needed, or return an error if unable to migrate +// the given data. +// +// MigrateMsg has some data on how to perform the migration. +func (w *Wasmer) Migrate( + newCodeId CodeID, + env types.Env, + migrateMsg []byte, + store KVStore, + goapi GoAPI, + querier Querier, + gasMeter GasMeter, + gasLimit uint64, + sigInfo types.VerificationInfo, +) (interface{}, uint64, error) { + paramBin, err := json.Marshal(env) + if err != nil { + return nil, 0, err + } + sigInfoBin, err := json.Marshal(sigInfo) + if err != nil { + return nil, 0, err + } + + data, gasUsed, err := api.Handle(w.cache, newCodeId, paramBin, migrateMsg, &gasMeter, store, &goapi, &querier, gasLimit, sigInfoBin, types.HandleTypeMigrate) + if err != nil { + return nil, gasUsed, err + } + + var resp ContractExecResponse + err = json.Unmarshal(data, &resp) + + if err != nil { + // unidentified response 🤷 + return nil, gasUsed, fmt.Errorf("handle: cannot parse response from json: %w", err) + } + + isOutputAddressedToReply := (len(resp.InternaReplyEnclaveSig) > 0 && len(resp.InternalMsgId) > 0) + + // handle v0.10 response + if resp.V010 != nil { + if resp.V010.Err != nil { //nolint:gocritic + return v1types.DataWithInternalReplyInfo{ + InternalMsgId: resp.InternalMsgId, + InternaReplyEnclaveSig: resp.InternaReplyEnclaveSig, + Data: []byte(resp.V010.Err.GenericErr.Msg), + }, gasUsed, fmt.Errorf("%+v", resp.V010.Err) + } else if resp.V010.Ok != nil { + if isOutputAddressedToReply { + resp.V010.Ok.Data, err = AppendReplyInternalDataToData(resp.V010.Ok.Data, resp.InternaReplyEnclaveSig, resp.InternalMsgId) + if err != nil { + return nil, gasUsed, fmt.Errorf("cannot serialize v0.10 DataWithInternalReplyInfo into binary : %w", err) + } + } + return resp.V010.Ok, gasUsed, nil + } else { + return nil, gasUsed, fmt.Errorf("cannot parse v0.10 handle response: %+v", resp) + } + } + + // handle v1 response + if resp.V1 != nil { + if resp.V1.Err != nil { //nolint:gocritic + return v1types.DataWithInternalReplyInfo{ + InternalMsgId: resp.InternalMsgId, + InternaReplyEnclaveSig: resp.InternaReplyEnclaveSig, + Data: []byte(resp.V1.Err.GenericErr.Msg), + }, gasUsed, fmt.Errorf("%+v", resp.V1.Err) + } else if resp.V1.Ok != nil { + if isOutputAddressedToReply { + resp.V1.Ok.Data, err = AppendReplyInternalDataToData(resp.V1.Ok.Data, resp.InternaReplyEnclaveSig, resp.InternalMsgId) + if err != nil { + return nil, gasUsed, fmt.Errorf("cannot serialize v1 DataWithInternalReplyInfo into binary: %w", err) + } + } + return resp.V1.Ok, gasUsed, nil + } else { + return nil, gasUsed, fmt.Errorf("cannot parse v1 handle response: %+v", resp) + } + } + + if resp.IBCBasic != nil { + if resp.IBCBasic.Err != nil { //nolint:gocritic + return nil, gasUsed, fmt.Errorf("%+v", resp.IBCBasic.Err) + } else if resp.IBCBasic.Ok != nil { + return resp.IBCBasic.Ok, gasUsed, nil + } else { + return nil, gasUsed, fmt.Errorf("cannot parse IBCBasic response: %+v", resp) + } + } + + if resp.IBCPacketReceive != nil { + if resp.IBCPacketReceive.Err != nil { //nolint:gocritic + return nil, gasUsed, fmt.Errorf("%+v", resp.IBCPacketReceive.Err) + } else if resp.IBCPacketReceive.Ok != nil { + return resp.IBCPacketReceive.Ok, gasUsed, nil + } else { + return nil, gasUsed, fmt.Errorf("cannot parse IBCPacketReceive response: %+v", resp) + } + } + + if resp.IBCChannelOpen != nil { + if resp.IBCChannelOpen.Err != nil { //nolint:gocritic + return nil, gasUsed, fmt.Errorf("%+v", resp.IBCChannelOpen.Err) + } else if resp.IBCChannelOpen.Ok != nil { + // ibc_channel_open actually returns no data + return resp.IBCChannelOpen.Ok, gasUsed, nil + } else { + return nil, gasUsed, fmt.Errorf("cannot parse IBCChannelOpen response: %+v", resp) + } + } + + return nil, gasUsed, fmt.Errorf("handle: cannot detect response type (v0.10 or v1)") +} diff --git a/go-cosmwasm/types/types.go b/go-cosmwasm/types/types.go index 83d166bb4..b50d041ef 100644 --- a/go-cosmwasm/types/types.go +++ b/go-cosmwasm/types/types.go @@ -78,6 +78,7 @@ const ( HandleTypeIbcPacketReceive HandleTypeIbcPacketAck HandleTypeIbcPacketTimeout + HandleTypeMigrate ) type CosmosMsgVersion int diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index 9afb3d7cc..cef94fb5d 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -1068,3 +1068,82 @@ func (k Keeper) UpdateContractAdmin(ctx sdk.Context, contractAddress, caller, ne return nil } + +func (k Keeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, newCodeID uint64, msg []byte) ([]byte, error) { + defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "migrate") + ctx.GasMeter().ConsumeGas(types.InstanceCost, "Loading CosmWasm module: migrate") + + signBytes, signMode, modeInfoBytes, pkBytes, signerSig, err := k.GetSignerInfo(ctx, caller) + if err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, err.Error()) + } + + verificationInfo := types.NewVerificationInfo(signBytes, signMode, modeInfoBytes, pkBytes, signerSig, nil) + + contractInfo, _, prefixStore, err := k.contractInstance(ctx, contractAddress) + if err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, sdkerrors.Wrap(err, "unknown contract").Error()) + } + + newCodeInfo, err := k.GetCodeInfo(ctx, newCodeID) + if err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, sdkerrors.Wrap(err, "unknown code").Error()) + } + + // check for IBC flag + switch report, err := k.wasmer.AnalyzeCode(newCodeInfo.CodeHash); { + case err != nil: + return nil, sdkerrors.Wrap(types.ErrMigrationFailed, err.Error()) + case !report.HasIBCEntryPoints && contractInfo.IBCPortID != "": + // prevent update of ibc contract to non ibc contract + return nil, sdkerrors.Wrap(types.ErrMigrationFailed, "requires ibc callbacks") + case report.HasIBCEntryPoints && contractInfo.IBCPortID == "": + // add ibc port + ibcPort, err := k.ensureIbcPort(ctx, contractAddress) + if err != nil { + return nil, err + } + contractInfo.IBCPortID = ibcPort + } + + store := ctx.KVStore(k.storeKey) + contractKey := store.Get(types.GetContractEnclaveKey(contractAddress)) + + env := types.NewEnv(ctx, caller, sdk.Coins{}, contractAddress, contractKey) + + // prepare querier + querier := QueryHandler{ + Ctx: ctx, + Plugins: k.queryPlugins, + Caller: contractAddress, + } + + // instantiate wasm contract + gas := gasForContract(ctx) + + res, gasUsed, err := k.wasmer.Migrate(newCodeInfo.CodeHash, env, msg, &prefixStore, cosmwasmAPI, &querier, gasMeter(ctx), gas, verificationInfo) + consumeGas(ctx, gasUsed) + if err != nil { + return nil, sdkerrors.Wrap(types.ErrMigrationFailed, err.Error()) + } + // delete old secondary index entry + k.removeFromContractCodeSecondaryIndex(ctx, contractAddress, k.getLastContractHistoryEntry(ctx, contractAddress)) + // persist migration updates + historyEntry := contractInfo.AddMigration(ctx, newCodeID, msg) + k.appendToContractHistory(ctx, contractAddress, historyEntry) + k.addToContractCodeSecondaryIndex(ctx, contractAddress, historyEntry) + k.storeContractInfo(ctx, contractAddress, contractInfo) + + ctx.EventManager().EmitEvent(sdk.NewEvent( + types.EventTypeMigrate, + sdk.NewAttribute(types.AttributeKeyCodeID, strconv.FormatUint(newCodeID, 10)), + sdk.NewAttribute(types.AttributeKeyContractAddr, contractAddress.String()), + )) + + data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res.Messages, res.Attributes, res.Data, res.Events) + if err != nil { + return nil, sdkerrors.Wrap(err, "dispatch") + } + + return data, nil +} diff --git a/x/compute/internal/types/types.go b/x/compute/internal/types/types.go index a433c20e1..de8b60f92 100644 --- a/x/compute/internal/types/types.go +++ b/x/compute/internal/types/types.go @@ -109,7 +109,7 @@ func NewAbsoluteTxPosition(ctx sdk.Context) *AbsoluteTxPosition { } // NewEnv initializes the environment for a contract instance -func NewEnv(ctx sdk.Context, creator sdk.AccAddress, deposit sdk.Coins, contractAddr sdk.AccAddress, contractKey []byte) wasmTypes.Env { +func NewEnv(ctx sdk.Context, caller sdk.AccAddress, deposit sdk.Coins, contractAddr sdk.AccAddress, contractKey []byte) wasmTypes.Env { // safety checks before casting below if ctx.BlockHeight() < 0 { panic("Block height must never be negative") @@ -125,7 +125,7 @@ func NewEnv(ctx sdk.Context, creator sdk.AccAddress, deposit sdk.Coins, contract ChainID: ctx.ChainID(), }, Message: wasmTypes.MessageInfo{ - Sender: creator.String(), + Sender: caller.String(), SentFunds: NewWasmCoins(deposit), }, Contract: wasmTypes.ContractInfo{ From 1233992fc64cced9dcddb5da52e2ae0b0ebb4fee Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Mon, 13 Feb 2023 13:41:00 +0200 Subject: [PATCH 005/164] Things are compiling --- x/compute/internal/keeper/keeper.go | 117 +++++++++++++++++++++++++--- x/compute/internal/types/keys.go | 64 ++++++++++++--- x/compute/internal/types/types.go | 14 ++++ 3 files changed, 176 insertions(+), 19 deletions(-) diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index cef94fb5d..67e309f7e 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -416,8 +416,8 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator sdk.AccAddre // persist instance createdAt := types.NewAbsoluteTxPosition(ctx) contractInfo := types.NewContractInfo(codeID, creator, admin, label, createdAt) - store.Set(types.GetContractAddressKey(contractAddress), k.cdc.MustMarshal(&contractInfo)) + k.storeContractInfo(ctx, contractAddress, &contractInfo) store.Set(types.GetContractEnclaveKey(contractAddress), key) store.Set(types.GetContractLabelPrefix(label), contractAddress) @@ -458,9 +458,8 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator sdk.AccAddre )) // persist instance - store.Set(types.GetContractAddressKey(contractAddress), k.cdc.MustMarshal(&contractInfo)) + k.storeContractInfo(ctx, contractAddress, &contractInfo) store.Set(types.GetContractEnclaveKey(contractAddress), key) - store.Set(types.GetContractLabelPrefix(label), contractAddress) data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res.Messages, res.Attributes, res.Events, res.Data, initMsg, verificationInfo, wasmTypes.CosmosMsgVersionV1) @@ -1121,18 +1120,29 @@ func (k Keeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller // instantiate wasm contract gas := gasForContract(ctx) - res, gasUsed, err := k.wasmer.Migrate(newCodeInfo.CodeHash, env, msg, &prefixStore, cosmwasmAPI, &querier, gasMeter(ctx), gas, verificationInfo) + response, gasUsed, err := k.wasmer.Execute(newCodeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, gasMeter(ctx), gas, verificationInfo, wasmTypes.HandleTypeMigrate) consumeGas(ctx, gasUsed) + if err != nil { - return nil, sdkerrors.Wrap(types.ErrMigrationFailed, err.Error()) + var result []byte + switch res := response.(type) { //nolint:gocritic + case v1wasmTypes.DataWithInternalReplyInfo: + result, err = json.Marshal(res) + if err != nil { + return nil, sdkerrors.Wrap(err, "couldn't marshal internal reply info") + } + } + + return result, sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) } + // delete old secondary index entry k.removeFromContractCodeSecondaryIndex(ctx, contractAddress, k.getLastContractHistoryEntry(ctx, contractAddress)) // persist migration updates historyEntry := contractInfo.AddMigration(ctx, newCodeID, msg) k.appendToContractHistory(ctx, contractAddress, historyEntry) k.addToContractCodeSecondaryIndex(ctx, contractAddress, historyEntry) - k.storeContractInfo(ctx, contractAddress, contractInfo) + k.storeContractInfo(ctx, contractAddress, &contractInfo) ctx.EventManager().EmitEvent(sdk.NewEvent( types.EventTypeMigrate, @@ -1140,10 +1150,97 @@ func (k Keeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.NewAttribute(types.AttributeKeyContractAddr, contractAddress.String()), )) - data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res.Messages, res.Attributes, res.Data, res.Events) - if err != nil { - return nil, sdkerrors.Wrap(err, "dispatch") + switch res := response.(type) { + case *v010wasmTypes.HandleResponse: + subMessages, err := V010MsgsToV1SubMsgs(contractAddress.String(), res.Messages) + if err != nil { + return nil, sdkerrors.Wrap(err, "couldn't convert v0.10 messages to v1 messages") + } + + data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, subMessages, res.Log, []v1wasmTypes.Event{}, res.Data, msg, verificationInfo, wasmTypes.CosmosMsgVersionV010) + if err != nil { + return nil, sdkerrors.Wrap(err, "dispatch") + } + + return data, nil + case *v1wasmTypes.Response: + ctx.EventManager().EmitEvent(sdk.NewEvent( + types.EventTypeExecute, + sdk.NewAttribute(types.AttributeKeyContractAddr, contractAddress.String()), + )) + + data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res.Messages, res.Attributes, res.Events, res.Data, msg, verificationInfo, wasmTypes.CosmosMsgVersionV1) + if err != nil { + return nil, sdkerrors.Wrap(err, "dispatch") + } + + return data, nil + default: + return nil, sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("cannot detect response type: %+v", res)) + } +} + +// getLastContractHistoryEntry returns the last element from history. To be used internally only as it panics when none exists +func (k Keeper) getLastContractHistoryEntry(ctx sdk.Context, contractAddr sdk.AccAddress) types.ContractCodeHistoryEntry { + prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), types.GetContractCodeHistoryElementPrefix(contractAddr)) + iter := prefixStore.ReverseIterator(nil, nil) + defer iter.Close() + + var r types.ContractCodeHistoryEntry + if !iter.Valid() { + // all contracts have a history + panic(fmt.Sprintf("no history for %s", contractAddr.String())) } + k.cdc.MustUnmarshal(iter.Value(), &r) + return r +} + +// removeFromContractCodeSecondaryIndex removes element to the index for contracts-by-codeid queries +func (k Keeper) removeFromContractCodeSecondaryIndex(ctx sdk.Context, contractAddress sdk.AccAddress, entry types.ContractCodeHistoryEntry) { + ctx.KVStore(k.storeKey).Delete(types.GetContractByCreatedSecondaryIndexKey(contractAddress, entry)) +} + +func (k Keeper) appendToContractHistory(ctx sdk.Context, contractAddr sdk.AccAddress, newEntries ...types.ContractCodeHistoryEntry) { + store := ctx.KVStore(k.storeKey) + // find last element position + var pos uint64 + prefixStore := prefix.NewStore(store, types.GetContractCodeHistoryElementPrefix(contractAddr)) + iter := prefixStore.ReverseIterator(nil, nil) + defer iter.Close() - return data, nil + if iter.Valid() { + pos = sdk.BigEndianToUint64(iter.Key()) + } + // then store with incrementing position + for _, e := range newEntries { + pos++ + key := types.GetContractCodeHistoryElementKey(contractAddr, pos) + store.Set(key, k.cdc.MustMarshal(&e)) //nolint:gosec + } +} + +func (k Keeper) GetContractHistory(ctx sdk.Context, contractAddr sdk.AccAddress) []types.ContractCodeHistoryEntry { + prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), types.GetContractCodeHistoryElementPrefix(contractAddr)) + r := make([]types.ContractCodeHistoryEntry, 0) + iter := prefixStore.Iterator(nil, nil) + defer iter.Close() + + for ; iter.Valid(); iter.Next() { + var e types.ContractCodeHistoryEntry + k.cdc.MustUnmarshal(iter.Value(), &e) + r = append(r, e) + } + return r +} + +// addToContractCodeSecondaryIndex adds element to the index for contracts-by-codeid queries +func (k Keeper) addToContractCodeSecondaryIndex(ctx sdk.Context, contractAddress sdk.AccAddress, entry types.ContractCodeHistoryEntry) { + store := ctx.KVStore(k.storeKey) + store.Set(types.GetContractByCreatedSecondaryIndexKey(contractAddress, entry), []byte{}) +} + +// storeContractInfo persists the ContractInfo. No secondary index updated here. +func (k Keeper) storeContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress, contract *types.ContractInfo) { + store := ctx.KVStore(k.storeKey) + store.Set(types.GetContractAddressKey(contractAddress), k.cdc.MustMarshal(contract)) } diff --git a/x/compute/internal/types/keys.go b/x/compute/internal/types/keys.go index 07cb486e2..8bd9d184c 100644 --- a/x/compute/internal/types/keys.go +++ b/x/compute/internal/types/keys.go @@ -24,15 +24,18 @@ const ( ) var ( - CodeKeyPrefix = []byte{0x01} - ContractKeyPrefix = []byte{0x02} - ContractStorePrefix = []byte{0x03} - SequenceKeyPrefix = []byte{0x04} - ContractEnclaveIdPrefix = []byte{0x06} - ContractLabelPrefix = []byte{0x07} - TXCounterPrefix = []byte{0x08} - KeyLastCodeID = append(SequenceKeyPrefix, []byte("lastCodeId")...) - KeyLastInstanceID = append(SequenceKeyPrefix, []byte("lastContractId")...) + CodeKeyPrefix = []byte{0x01} + ContractKeyPrefix = []byte{0x02} + ContractStorePrefix = []byte{0x03} + SequenceKeyPrefix = []byte{0x04} + ContractEnclaveIdPrefix = []byte{0x06} + ContractLabelPrefix = []byte{0x07} + TXCounterPrefix = []byte{0x08} + ContractCodeHistoryElementPrefix = []byte{0x09} + ContractByCodeIDAndCreatedSecondaryIndexPrefix = []byte{0x0A} + + KeyLastCodeID = append(SequenceKeyPrefix, []byte("lastCodeId")...) + KeyLastInstanceID = append(SequenceKeyPrefix, []byte("lastContractId")...) ) // GetCodeKey constructs the key for retreiving the ID for the WASM code @@ -64,3 +67,46 @@ func GetContractStorePrefixKey(addr sdk.AccAddress) []byte { func GetContractLabelPrefix(addr string) []byte { return append(ContractLabelPrefix, []byte(addr)...) } + +// GetContractCodeHistoryElementPrefix returns the key prefix for a contract code history entry: `` +func GetContractCodeHistoryElementPrefix(contractAddr sdk.AccAddress) []byte { + prefixLen := len(ContractCodeHistoryElementPrefix) + contractAddrLen := len(contractAddr) + r := make([]byte, prefixLen+contractAddrLen) + copy(r[0:], ContractCodeHistoryElementPrefix) + copy(r[prefixLen:], contractAddr) + return r +} + +// GetContractByCreatedSecondaryIndexKey returns the key for the secondary index: +// `` +func GetContractByCreatedSecondaryIndexKey(contractAddr sdk.AccAddress, c ContractCodeHistoryEntry) []byte { + prefix := GetContractByCodeIDSecondaryIndexPrefix(c.CodeID) + prefixLen := len(prefix) + contractAddrLen := len(contractAddr) + r := make([]byte, prefixLen+AbsoluteTxPositionLen+contractAddrLen) + copy(r[0:], prefix) + copy(r[prefixLen:], c.Updated.Bytes()) + copy(r[prefixLen+AbsoluteTxPositionLen:], contractAddr) + return r +} + +// GetContractByCodeIDSecondaryIndexPrefix returns the prefix for the second index: `` +func GetContractByCodeIDSecondaryIndexPrefix(codeID uint64) []byte { + prefixLen := len(ContractByCodeIDAndCreatedSecondaryIndexPrefix) + const codeIDLen = 8 + r := make([]byte, prefixLen+codeIDLen) + copy(r[0:], ContractByCodeIDAndCreatedSecondaryIndexPrefix) + copy(r[prefixLen:], sdk.Uint64ToBigEndian(codeID)) + return r +} + +// GetContractCodeHistoryElementKey returns the key a contract code history entry: `` +func GetContractCodeHistoryElementKey(contractAddr sdk.AccAddress, pos uint64) []byte { + prefix := GetContractCodeHistoryElementPrefix(contractAddr) + prefixLen := len(prefix) + r := make([]byte, prefixLen+8) + copy(r[0:], prefix) + copy(r[prefixLen:], sdk.Uint64ToBigEndian(pos)) + return r +} diff --git a/x/compute/internal/types/types.go b/x/compute/internal/types/types.go index de8b60f92..707ddc382 100644 --- a/x/compute/internal/types/types.go +++ b/x/compute/internal/types/types.go @@ -108,6 +108,20 @@ func NewAbsoluteTxPosition(ctx sdk.Context) *AbsoluteTxPosition { } } +// AbsoluteTxPositionLen number of elements in byte representation +const AbsoluteTxPositionLen = 16 + +// Bytes encodes the object into a 16 byte representation with big endian block height and tx index. +func (a *AbsoluteTxPosition) Bytes() []byte { + if a == nil { + panic("object must not be nil") + } + r := make([]byte, AbsoluteTxPositionLen) + copy(r[0:], sdk.Uint64ToBigEndian(uint64(a.BlockHeight))) + copy(r[8:], sdk.Uint64ToBigEndian(a.TxIndex)) + return r +} + // NewEnv initializes the environment for a contract instance func NewEnv(ctx sdk.Context, caller sdk.AccAddress, deposit sdk.Coins, contractAddr sdk.AccAddress, contractKey []byte) wasmTypes.Env { // safety checks before casting below From 977948e3b3b2a946767941bda1838610e5cec64f Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Sun, 19 Feb 2023 11:23:22 +0200 Subject: [PATCH 006/164] Checkpoint: some progress passing admin into the enclave on init() --- cosmwasm/enclaves/execute/Enclave.edl | 4 +- .../src/contract_operations.rs | 5 +- .../src/contract_validation.rs | 2 +- .../contract-engine/src/external/ecalls.rs | 4 + cosmwasm/packages/sgx-vm/src/calls.rs | 5 +- cosmwasm/packages/sgx-vm/src/instance.rs | 18 +- cosmwasm/packages/sgx-vm/src/wasmi/imports.rs | 2 + cosmwasm/packages/sgx-vm/src/wasmi/wrapper.rs | 10 +- go-cosmwasm/api/bindings.h | 3 +- go-cosmwasm/api/lib.go | 6 +- go-cosmwasm/api/lib_mock.go | 32 +- go-cosmwasm/lib.go | 4 +- go-cosmwasm/src/lib.rs | 7 +- proto/secret/compute/v1beta1/query.proto | 25 + x/compute/client/cli/query.go | 64 ++ x/compute/client/cli/tx.go | 115 +++ x/compute/internal/keeper/keeper.go | 2 +- x/compute/internal/types/query.pb.go | 700 ++++++++++++++++-- x/compute/internal/types/query.pb.gw.go | 116 +++ 19 files changed, 1005 insertions(+), 119 deletions(-) diff --git a/cosmwasm/enclaves/execute/Enclave.edl b/cosmwasm/enclaves/execute/Enclave.edl index 6aaced921..c0e4e1b48 100644 --- a/cosmwasm/enclaves/execute/Enclave.edl +++ b/cosmwasm/enclaves/execute/Enclave.edl @@ -68,7 +68,9 @@ enclave { [in, count=msg_len] const uint8_t* msg, uintptr_t msg_len, [in, count=sig_info_len] const uint8_t* sig_info, - uintptr_t sig_info_len + uintptr_t sig_info_len, + [in, count=admin_len] const uint8_t* admin, + uintptr_t admin_len ); public HandleResult ecall_handle( diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 723e8167d..47c5a5f9f 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -18,7 +18,7 @@ use crate::external::results::{HandleSuccess, InitSuccess, QuerySuccess}; use crate::message::{is_ibc_msg, parse_message, ParsedMessage}; use super::contract_validation::{ - generate_encryption_key, validate_contract_key, validate_msg, verify_params, ContractKey, + generate_contract_key, validate_contract_key, validate_msg, verify_params, ContractKey, }; use super::gas::WasmCosts; use super::io::{ @@ -52,6 +52,7 @@ pub fn init( env: &[u8], // blockchain state msg: &[u8], // probably function call and args sig_info: &[u8], // info about signature verification + admin: &[u8], // admin's canonical address or null if no admin ) -> Result { trace!("Starting init"); @@ -76,7 +77,7 @@ pub fn init( let canonical_sender_address = to_canonical(sender)?; - let contract_key = generate_encryption_key( + let contract_key = generate_contract_key( &canonical_sender_address, &block_height, &contract_hash, diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index 7cebe32ba..824b9bb9a 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -23,7 +23,7 @@ pub const CONTRACT_KEY_LENGTH: usize = HASH_SIZE + HASH_SIZE; const HEX_ENCODED_HASH_SIZE: usize = HASH_SIZE * 2; const SIZE_OF_U64: usize = 8; -pub fn generate_encryption_key( +pub fn generate_contract_key( sender: &CanonicalAddr, block_height: &u64, contract_hash: &[u8; HASH_SIZE], diff --git a/cosmwasm/enclaves/shared/contract-engine/src/external/ecalls.rs b/cosmwasm/enclaves/shared/contract-engine/src/external/ecalls.rs index a0bf5d8fb..187aa848b 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/external/ecalls.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/external/ecalls.rs @@ -160,6 +160,8 @@ pub unsafe extern "C" fn ecall_init( msg_len: usize, sig_info: *const u8, sig_info_len: usize, + admin: *const u8, + admin_len: usize, ) -> InitResult { // let _recursion_guard = match recursion_depth::guard() { // Ok(rg) => rg, @@ -190,6 +192,7 @@ pub unsafe extern "C" fn ecall_init( let env = std::slice::from_raw_parts(env, env_len); let msg = std::slice::from_raw_parts(msg, msg_len); let sig_info = std::slice::from_raw_parts(sig_info, sig_info_len); + let admin = std::slice::from_raw_parts(admin, admin_len); let result = panic::catch_unwind(|| { let mut local_used_gas = *used_gas; let result = crate::contract_operations::init( @@ -200,6 +203,7 @@ pub unsafe extern "C" fn ecall_init( env, msg, sig_info, + admin, ); *used_gas = local_used_gas; result_init_success_to_initresult(result) diff --git a/cosmwasm/packages/sgx-vm/src/calls.rs b/cosmwasm/packages/sgx-vm/src/calls.rs index c32393827..2e6689887 100644 --- a/cosmwasm/packages/sgx-vm/src/calls.rs +++ b/cosmwasm/packages/sgx-vm/src/calls.rs @@ -79,12 +79,13 @@ pub fn call_init_raw VmResult> { instance.set_storage_readonly(false); /* call_raw(instance, "init", &[env, msg], MAX_LENGTH_INIT) */ - instance.call_init(env, msg, sig_info) + instance.call_init(env, msg, sig_info, admin) } /// Calls Wasm export "handle" and returns raw data from the contract. @@ -94,7 +95,7 @@ pub fn call_handle_raw VmResult> { instance.set_storage_readonly(false); /* diff --git a/cosmwasm/packages/sgx-vm/src/instance.rs b/cosmwasm/packages/sgx-vm/src/instance.rs index 798d7475a..3f0644533 100644 --- a/cosmwasm/packages/sgx-vm/src/instance.rs +++ b/cosmwasm/packages/sgx-vm/src/instance.rs @@ -326,12 +326,24 @@ where Ok(function) } - pub fn call_init(&mut self, env: &[u8], msg: &[u8], sig_info: &[u8]) -> VmResult> { - let result = self.inner.init(env, msg, sig_info)?; + pub fn call_init( + &mut self, + env: &[u8], + msg: &[u8], + sig_info: &[u8], + admin: &[u8], + ) -> VmResult> { + let result = self.inner.init(env, msg, sig_info, admin)?; Ok(result.into_output()) } - pub fn call_handle(&mut self, env: &[u8], msg: &[u8], sig_info: &[u8], handle_type: u8) -> VmResult> { + pub fn call_handle( + &mut self, + env: &[u8], + msg: &[u8], + sig_info: &[u8], + handle_type: u8, + ) -> VmResult> { let result = self.inner.handle(env, msg, sig_info, handle_type)?; Ok(result.into_output()) } diff --git a/cosmwasm/packages/sgx-vm/src/wasmi/imports.rs b/cosmwasm/packages/sgx-vm/src/wasmi/imports.rs index 6b73bcb9e..031f7a85e 100644 --- a/cosmwasm/packages/sgx-vm/src/wasmi/imports.rs +++ b/cosmwasm/packages/sgx-vm/src/wasmi/imports.rs @@ -32,6 +32,8 @@ extern "C" { msg_len: usize, sig_info: *const u8, sig_info_len: usize, + admin: *const u8, + admin_len: usize, ) -> sgx_status_t; /// Trigger a handle method in a wasm contract diff --git a/cosmwasm/packages/sgx-vm/src/wasmi/wrapper.rs b/cosmwasm/packages/sgx-vm/src/wasmi/wrapper.rs index 867c0a594..8060acd65 100644 --- a/cosmwasm/packages/sgx-vm/src/wasmi/wrapper.rs +++ b/cosmwasm/packages/sgx-vm/src/wasmi/wrapper.rs @@ -92,7 +92,13 @@ where VmError::generic_err("The enclave is too busy and can not respond to this query") } - pub fn init(&mut self, env: &[u8], msg: &[u8], sig_info: &[u8]) -> VmResult { + pub fn init( + &mut self, + env: &[u8], + msg: &[u8], + sig_info: &[u8], + admin: &[u8], + ) -> VmResult { trace!( "init() called with env: {:?} msg: {:?} gas_left: {}", String::from_utf8_lossy(env), @@ -125,6 +131,8 @@ where msg.len(), sig_info.as_ptr(), sig_info.len(), + admin.as_ptr(), + admin.len(), ) }; diff --git a/go-cosmwasm/api/bindings.h b/go-cosmwasm/api/bindings.h index b94f7e37f..3b62d73a8 100644 --- a/go-cosmwasm/api/bindings.h +++ b/go-cosmwasm/api/bindings.h @@ -190,7 +190,8 @@ Buffer instantiate(cache_t *cache, uint64_t gas_limit, uint64_t *gas_used, Buffer *err, - Buffer sig_info); + Buffer sig_info, + Buffer admin); Buffer key_gen(Buffer *err); diff --git a/go-cosmwasm/api/lib.go b/go-cosmwasm/api/lib.go index ac26f5624..597038fb8 100644 --- a/go-cosmwasm/api/lib.go +++ b/go-cosmwasm/api/lib.go @@ -142,6 +142,7 @@ func Instantiate( querier *Querier, gasLimit uint64, sigInfo []byte, + admin []byte, ) ([]byte, uint64, error) { id := sendSlice(code_id) defer freeAfterSend(id) @@ -164,12 +165,15 @@ func Instantiate( var gasUsed u64 errmsg := C.Buffer{} + adminBuffer := sendSlice(admin) + defer freeAfterSend(adminBuffer) + //// This is done in order to ensure that goroutines don't //// swap threads between recursive calls to the enclave. //runtime.LockOSThread() //defer runtime.UnlockOSThread() - res, err := C.instantiate(cache.ptr, id, p, m, db, a, q, u64(gasLimit), &gasUsed, &errmsg, s) + res, err := C.instantiate(cache.ptr, id, p, m, db, a, q, u64(gasLimit), &gasUsed, &errmsg, s, adminBuffer) if err != nil && err.(syscall.Errno) != C.ErrnoValue_Success { // Depending on the nature of the error, `gasUsed` will either have a meaningful value, or just 0. return nil, uint64(gasUsed), errorWithMessage(err, errmsg) diff --git a/go-cosmwasm/api/lib_mock.go b/go-cosmwasm/api/lib_mock.go index 8ccd13640..f5d5fe754 100644 --- a/go-cosmwasm/api/lib_mock.go +++ b/go-cosmwasm/api/lib_mock.go @@ -119,6 +119,7 @@ func Instantiate( querier *Querier, gasLimit uint64, sigInfo []byte, + admin []byte, ) ([]byte, uint64, error) { //id := sendSlice(code_id) //defer freeAfterSend(id) @@ -173,37 +174,6 @@ func Handle( return nil, 0, nil } -func Migrate( - cache Cache, - code_id []byte, - params []byte, - msg []byte, - gasMeter *GasMeter, - store KVStore, - api *GoAPI, - querier *Querier, - gasLimit uint64, -) ([]byte, uint64, error) { - //id := sendSlice(code_id) - //defer freeAfterSend(id) - //p := sendSlice(params) - //defer freeAfterSend(p) - //m := sendSlice(msg) - //defer freeAfterSend(m) - //db := buildDB(store, gasMeter) - //a := buildAPI(api) - //q := buildQuerier(querier) - //var gasUsed u64 - //errmsg := C.Buffer{} - //res, err := C.migrate(cache.ptr, id, p, m, db, a, q, u64(gasLimit), &gasUsed, &errmsg) - //if err != nil && err.(syscall.Errno) != C.ErrnoValue_Success { - // // Depending on the nature of the error, `gasUsed` will either have a meaningful value, or just 0. - // return nil, uint64(gasUsed), errorWithMessage(err, errmsg) - //} - //return receiveVector(res), uint64(gasUsed), nil - return nil, 0, nil -} - func Query( cache Cache, code_id []byte, diff --git a/go-cosmwasm/lib.go b/go-cosmwasm/lib.go index 67d86dd11..1b860552f 100644 --- a/go-cosmwasm/lib.go +++ b/go-cosmwasm/lib.go @@ -140,7 +140,7 @@ func (w *Wasmer) Instantiate( gasMeter GasMeter, gasLimit uint64, sigInfo types.VerificationInfo, - contractAddress sdk.AccAddress, + admin sdk.AccAddress, ) (interface{}, []byte, uint64, error) { paramBin, err := json.Marshal(env) if err != nil { @@ -152,7 +152,7 @@ func (w *Wasmer) Instantiate( return nil, nil, 0, err } - data, gasUsed, err := api.Instantiate(w.cache, codeId, paramBin, initMsg, &gasMeter, store, &goapi, &querier, gasLimit, sigInfoBin) + data, gasUsed, err := api.Instantiate(w.cache, codeId, paramBin, initMsg, &gasMeter, store, &goapi, &querier, gasLimit, sigInfoBin, admin) if err != nil { return nil, nil, gasUsed, err } diff --git a/go-cosmwasm/src/lib.rs b/go-cosmwasm/src/lib.rs index 335c5111e..153285d62 100644 --- a/go-cosmwasm/src/lib.rs +++ b/go-cosmwasm/src/lib.rs @@ -231,6 +231,7 @@ static MSG_ARG: &str = "msg"; static PARAMS_ARG: &str = "params"; static GAS_USED_ARG: &str = "gas_used"; static SIG_INFO_ARG: &str = "sig_info"; +static ADMIN_ARG: &str = "admin"; fn do_init_cache( data_dir: Buffer, @@ -339,6 +340,7 @@ pub extern "C" fn instantiate( gas_used: Option<&mut u64>, err: Option<&mut Buffer>, sig_info: Buffer, + admin: Buffer, ) -> Buffer { let r = match to_cache(cache) { Some(c) => catch_unwind(AssertUnwindSafe(move || { @@ -353,6 +355,7 @@ pub extern "C" fn instantiate( gas_limit, gas_used, sig_info, + admin, ) })) .unwrap_or_else(|_| Err(Error::panic())), @@ -374,6 +377,7 @@ fn do_init( gas_limit: u64, gas_used: Option<&mut u64>, sig_info: Buffer, + admin: Buffer, ) -> Result, Error> { let gas_used = gas_used.ok_or_else(|| Error::empty_arg(GAS_USED_ARG))?; let code_id: Checksum = unsafe { code_id.read() } @@ -382,11 +386,12 @@ fn do_init( let params = unsafe { params.read() }.ok_or_else(|| Error::empty_arg(PARAMS_ARG))?; let msg = unsafe { msg.read() }.ok_or_else(|| Error::empty_arg(MSG_ARG))?; let sig_info = unsafe { sig_info.read() }.ok_or_else(|| Error::empty_arg(SIG_INFO_ARG))?; + let admin = unsafe { admin.read() }.ok_or_else(|| Error::empty_arg(ADMIN_ARG))?; let deps = to_extern(db, api, querier); let mut instance = cache.get_instance(&code_id, deps, gas_limit)?; // We only check this result after reporting gas usage and returning the instance into the cache. - let res = call_init_raw(&mut instance, params, msg, sig_info); + let res = call_init_raw(&mut instance, params, msg, sig_info, admin); *gas_used = instance.create_gas_report().used_internally; instance.recycle(); Ok(res?) diff --git a/proto/secret/compute/v1beta1/query.proto b/proto/secret/compute/v1beta1/query.proto index f1a447f92..1ae0acdce 100644 --- a/proto/secret/compute/v1beta1/query.proto +++ b/proto/secret/compute/v1beta1/query.proto @@ -6,6 +6,7 @@ import "secret/compute/v1beta1/types.proto"; import "google/protobuf/empty.proto"; import "google/api/annotations.proto"; import "cosmos/base/abci/v1beta1/abci.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; option go_package = "github.com/scrtlabs/SecretNetwork/x/compute/internal/types"; option (gogoproto.goproto_getters_all) = false; @@ -60,6 +61,12 @@ service Query { option (google.api.http).get = "/compute/v1beta1/contract_address/{label}"; } + // ContractHistory gets the contract code history + rpc ContractHistory(QueryContractHistoryRequest) + returns (QueryContractHistoryResponse) { + option (google.api.http).get = + "/compute/v1beta1/contract_history/{contract_address}"; + } } message QuerySecretContractRequest { @@ -146,4 +153,22 @@ message DecryptedAnswers { [ (gogoproto.nullable) = false ]; string output_error = 3; string plaintext_error = 4; +} + +// QueryContractHistoryRequest is the request type for the Query/ContractHistory +// RPC method +message QueryContractHistoryRequest { + // address is the address of the contract to query + string contract_address = 1; + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryContractHistoryResponse is the response type for the +// Query/ContractHistory RPC method +message QueryContractHistoryResponse { + repeated ContractCodeHistoryEntry entries = 1 + [ (gogoproto.nullable) = false ]; + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; } \ No newline at end of file diff --git a/x/compute/client/cli/query.go b/x/compute/client/cli/query.go index e3bf8f93d..c5f9763bb 100644 --- a/x/compute/client/cli/query.go +++ b/x/compute/client/cli/query.go @@ -2,6 +2,7 @@ package cli import ( "bytes" + "context" "encoding/base64" "encoding/hex" "encoding/json" @@ -50,6 +51,7 @@ func GetQueryCmd() *cobra.Command { GetCmdCodeHashByContractAddress(), GetCmdCodeHashByCodeID(), CmdDecryptText(), + GetCmdGetContractHistory(), ) return queryCmd } @@ -711,3 +713,65 @@ func (a *argumentDecoder) DecodeString(s string) ([]byte, error) { func asciiDecodeString(s string) ([]byte, error) { return []byte(s), nil } + +// GetCmdGetContractHistory prints the code history for a given contract +func GetCmdGetContractHistory() *cobra.Command { + cmd := &cobra.Command{ + Use: "contract-history [bech32_address]", + Short: "Prints out the code history for a contract given its address", + Long: "Prints out the code history for a contract given its address", + Aliases: []string{"history", "hist", "ch"}, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + _, err = sdk.AccAddressFromBech32(args[0]) + if err != nil { + return err + } + + pageReq, err := client.ReadPageRequest(withPageKeyDecoded(cmd.Flags())) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + res, err := queryClient.ContractHistory( + context.Background(), + &types.QueryContractHistoryRequest{ + ContractAddress: args[0], + Pagination: pageReq, + }, + ) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + SilenceUsage: true, + } + + flags.AddQueryFlagsToCmd(cmd) + flags.AddPaginationFlagsToCmd(cmd, "contract history") + return cmd +} + +// sdk ReadPageRequest expects binary but we encoded to base64 in our marshaller +func withPageKeyDecoded(flagSet *flag.FlagSet) *flag.FlagSet { + encoded, err := flagSet.GetString(flags.FlagPageKey) + if err != nil { + panic(err.Error()) + } + raw, err := base64.StdEncoding.DecodeString(encoded) + if err != nil { + panic(err.Error()) + } + err = flagSet.Set(flags.FlagPageKey, string(raw)) + if err != nil { + panic(err.Error()) + } + return flagSet +} diff --git a/x/compute/client/cli/tx.go b/x/compute/client/cli/tx.go index 5059bed04..a950ecbf9 100644 --- a/x/compute/client/cli/tx.go +++ b/x/compute/client/cli/tx.go @@ -14,6 +14,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" wasmUtils "github.com/scrtlabs/SecretNetwork/x/compute/client/utils" "github.com/scrtlabs/SecretNetwork/x/compute/internal/types" "github.com/spf13/cobra" @@ -47,6 +48,9 @@ func GetTxCmd() *cobra.Command { StoreCodeCmd(), InstantiateContractCmd(), ExecuteContractCmd(), + MigrateContractCmd(), + UpdateContractAdminCmd(), + ClearContractAdminCmd(), ) return txCmd } @@ -406,3 +410,114 @@ func GetCodeHashByContractAddr(cliCtx client.Context, contractAddr sdk.AccAddres return []byte(hex.EncodeToString(res)), nil } + +// MigrateContractCmd will migrate a contract to a new code version +func MigrateContractCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "migrate [contract_addr_bech32] [new_code_id_int64] [json_encoded_migration_args]", + Short: "Migrate a wasm contract to a new code version", + Aliases: []string{"update", "mig", "m"}, + Args: cobra.ExactArgs(3), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + msg, err := parseMigrateContractArgs(args, clientCtx) + if err != nil { + return err + } + if err := msg.ValidateBasic(); err != nil { + return nil + } + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg) + }, + SilenceUsage: true, + } + flags.AddTxFlagsToCmd(cmd) + return cmd +} + +func parseMigrateContractArgs(args []string, cliCtx client.Context) (types.MsgMigrateContract, error) { + // get the id of the code to instantiate + codeID, err := strconv.ParseUint(args[1], 10, 64) + if err != nil { + return types.MsgMigrateContract{}, sdkerrors.Wrap(err, "code id") + } + + migrateMsg := args[2] + + msg := types.MsgMigrateContract{ + Sender: cliCtx.GetFromAddress().String(), + Contract: args[0], + CodeID: codeID, + Msg: []byte(migrateMsg), + } + return msg, nil +} + +// UpdateContractAdminCmd sets an new admin for a contract +func UpdateContractAdminCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "set-contract-admin [contract_addr_bech32] [new_admin_addr_bech32]", + Short: "Set new admin for a contract", + Aliases: []string{"new-admin", "admin", "set-adm", "sa"}, + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + msg, err := parseUpdateContractAdminArgs(args, clientCtx) + if err != nil { + return err + } + if err := msg.ValidateBasic(); err != nil { + return err + } + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg) + }, + SilenceUsage: true, + } + flags.AddTxFlagsToCmd(cmd) + return cmd +} + +func parseUpdateContractAdminArgs(args []string, cliCtx client.Context) (types.MsgUpdateAdmin, error) { + msg := types.MsgUpdateAdmin{ + Sender: cliCtx.GetFromAddress().String(), + Contract: args[0], + NewAdmin: args[1], + } + return msg, nil +} + +// ClearContractAdminCmd clears an admin for a contract +func ClearContractAdminCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "clear-contract-admin [contract_addr_bech32]", + Short: "Clears admin for a contract to prevent further migrations", + Aliases: []string{"clear-admin", "clr-adm"}, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + msg := types.MsgClearAdmin{ + Sender: clientCtx.GetFromAddress().String(), + Contract: args[0], + } + if err := msg.ValidateBasic(); err != nil { + return err + } + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg) + }, + SilenceUsage: true, + } + flags.AddTxFlagsToCmd(cmd) + return cmd +} diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index 67e309f7e..b1e569801 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -392,7 +392,7 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator sdk.AccAddre // instantiate wasm contract gas := gasForContract(ctx) - response, key, gasUsed, err := k.wasmer.Instantiate(codeInfo.CodeHash, env, initMsg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, verificationInfo, contractAddress) + response, key, gasUsed, err := k.wasmer.Instantiate(codeInfo.CodeHash, env, initMsg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, verificationInfo, admin) consumeGas(ctx, gasUsed) if err != nil { diff --git a/x/compute/internal/types/query.pb.go b/x/compute/internal/types/query.pb.go index 37c00d5ae..62ccd47db 100644 --- a/x/compute/internal/types/query.pb.go +++ b/x/compute/internal/types/query.pb.go @@ -8,6 +8,7 @@ import ( context "context" fmt "fmt" types "github.com/cosmos/cosmos-sdk/types" + query "github.com/cosmos/cosmos-sdk/types/query" _ "github.com/gogo/protobuf/gogoproto" grpc1 "github.com/gogo/protobuf/grpc" proto "github.com/gogo/protobuf/proto" @@ -647,6 +648,89 @@ func (m *DecryptedAnswers) XXX_DiscardUnknown() { var xxx_messageInfo_DecryptedAnswers proto.InternalMessageInfo +// QueryContractHistoryRequest is the request type for the Query/ContractHistory +// RPC method +type QueryContractHistoryRequest struct { + // address is the address of the contract to query + ContractAddress string `protobuf:"bytes,1,opt,name=contract_address,json=contractAddress,proto3" json:"contract_address,omitempty"` + // pagination defines an optional pagination for the request. + Pagination *query.PageRequest `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QueryContractHistoryRequest) Reset() { *m = QueryContractHistoryRequest{} } +func (m *QueryContractHistoryRequest) String() string { return proto.CompactTextString(m) } +func (*QueryContractHistoryRequest) ProtoMessage() {} +func (*QueryContractHistoryRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_7735281c5fa969d4, []int{16} +} +func (m *QueryContractHistoryRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryContractHistoryRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryContractHistoryRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryContractHistoryRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryContractHistoryRequest.Merge(m, src) +} +func (m *QueryContractHistoryRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryContractHistoryRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryContractHistoryRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryContractHistoryRequest proto.InternalMessageInfo + +// QueryContractHistoryResponse is the response type for the +// Query/ContractHistory RPC method +type QueryContractHistoryResponse struct { + Entries []ContractCodeHistoryEntry `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries"` + // pagination defines the pagination in the response. + Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QueryContractHistoryResponse) Reset() { *m = QueryContractHistoryResponse{} } +func (m *QueryContractHistoryResponse) String() string { return proto.CompactTextString(m) } +func (*QueryContractHistoryResponse) ProtoMessage() {} +func (*QueryContractHistoryResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_7735281c5fa969d4, []int{17} +} +func (m *QueryContractHistoryResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryContractHistoryResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryContractHistoryResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryContractHistoryResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryContractHistoryResponse.Merge(m, src) +} +func (m *QueryContractHistoryResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryContractHistoryResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryContractHistoryResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryContractHistoryResponse proto.InternalMessageInfo + func init() { proto.RegisterType((*QuerySecretContractRequest)(nil), "secret.compute.v1beta1.QuerySecretContractRequest") proto.RegisterType((*QueryByLabelRequest)(nil), "secret.compute.v1beta1.QueryByLabelRequest") @@ -664,6 +748,8 @@ func init() { proto.RegisterType((*QueryCodeHashResponse)(nil), "secret.compute.v1beta1.QueryCodeHashResponse") proto.RegisterType((*DecryptedAnswer)(nil), "secret.compute.v1beta1.DecryptedAnswer") proto.RegisterType((*DecryptedAnswers)(nil), "secret.compute.v1beta1.DecryptedAnswers") + proto.RegisterType((*QueryContractHistoryRequest)(nil), "secret.compute.v1beta1.QueryContractHistoryRequest") + proto.RegisterType((*QueryContractHistoryResponse)(nil), "secret.compute.v1beta1.QueryContractHistoryResponse") } func init() { @@ -671,79 +757,87 @@ func init() { } var fileDescriptor_7735281c5fa969d4 = []byte{ - // 1145 bytes of a gzipped FileDescriptorProto + // 1278 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x57, 0xcf, 0x6f, 0x1b, 0x45, - 0x14, 0xf6, 0xb4, 0x4e, 0xd2, 0xbc, 0x84, 0x24, 0x1d, 0xd2, 0xd4, 0x75, 0x8a, 0xd3, 0x2e, 0x85, - 0x24, 0x4d, 0xd9, 0xc5, 0x6e, 0x01, 0xa9, 0xb7, 0x24, 0x8d, 0x44, 0x50, 0x00, 0xe1, 0x1e, 0x90, - 0x50, 0x91, 0x35, 0xde, 0x9d, 0x38, 0xab, 0x3a, 0x3b, 0xee, 0xce, 0xb8, 0x89, 0x85, 0xc2, 0x81, - 0x13, 0x47, 0x24, 0x40, 0x42, 0x9c, 0x38, 0x41, 0xc5, 0x01, 0x89, 0xff, 0x22, 0x07, 0x0e, 0x91, - 0xb8, 0x70, 0x8a, 0x20, 0xe1, 0x80, 0xb8, 0x73, 0x47, 0xf3, 0x63, 0x37, 0xbb, 0xf1, 0x26, 0xb6, - 0xcb, 0x81, 0xdb, 0xce, 0xcc, 0x9b, 0xf7, 0x7d, 0xef, 0x7b, 0x33, 0xef, 0xcd, 0x82, 0xc5, 0xa9, - 0x1b, 0x52, 0xe1, 0xb8, 0x6c, 0xbb, 0xd5, 0x16, 0xd4, 0x79, 0x5a, 0xae, 0x53, 0x41, 0xca, 0xce, - 0x93, 0x36, 0x0d, 0x3b, 0x76, 0x2b, 0x64, 0x82, 0xe1, 0x19, 0x6d, 0x63, 0x1b, 0x1b, 0xdb, 0xd8, - 0x14, 0xa7, 0x1b, 0xac, 0xc1, 0x94, 0x89, 0x23, 0xbf, 0xb4, 0x75, 0xf1, 0x2c, 0x8f, 0xa2, 0xd3, - 0xa2, 0xdc, 0xd8, 0xcc, 0x36, 0x18, 0x6b, 0x34, 0xa9, 0xa3, 0x46, 0xf5, 0xf6, 0xa6, 0x43, 0xb7, - 0x5b, 0xc2, 0xc0, 0x15, 0xaf, 0x9b, 0x45, 0xd2, 0xf2, 0x1d, 0x12, 0x04, 0x4c, 0x10, 0xe1, 0xb3, - 0x20, 0xda, 0xfa, 0xb2, 0xcb, 0xf8, 0x36, 0xe3, 0x4e, 0x9d, 0x70, 0xea, 0x90, 0xba, 0xeb, 0xc7, - 0x00, 0x72, 0xa0, 0x8d, 0xac, 0x8f, 0xa1, 0xf8, 0x81, 0x0c, 0xe0, 0xa1, 0xa2, 0xb2, 0xca, 0x02, - 0x11, 0x12, 0x57, 0x54, 0xe9, 0x93, 0x36, 0xe5, 0x02, 0x2f, 0xc2, 0x94, 0x6b, 0xa6, 0x6a, 0xc4, - 0xf3, 0x42, 0xca, 0x79, 0x01, 0xdd, 0x40, 0x0b, 0xa3, 0xd5, 0xc9, 0x68, 0x7e, 0x59, 0x4f, 0xe3, - 0x69, 0x18, 0x52, 0x4a, 0x14, 0x2e, 0xdc, 0x40, 0x0b, 0xe3, 0x55, 0x3d, 0xb0, 0x96, 0xe0, 0x45, - 0xe5, 0x7e, 0xa5, 0xb3, 0x41, 0xea, 0xb4, 0x19, 0xf9, 0x9d, 0x86, 0xa1, 0xa6, 0x1c, 0x1b, 0x67, - 0x7a, 0x60, 0xbd, 0x03, 0x2f, 0x19, 0xe3, 0xd5, 0xb4, 0xf3, 0xc1, 0xe9, 0x58, 0x0e, 0x4c, 0xc7, - 0xbe, 0x3c, 0xba, 0xee, 0x45, 0x2e, 0xae, 0xc2, 0x88, 0xcb, 0x3c, 0x5a, 0xf3, 0x3d, 0xb5, 0x33, - 0x5f, 0x1d, 0x76, 0xd5, 0xba, 0x55, 0x86, 0xd9, 0x4c, 0x21, 0x78, 0x8b, 0x05, 0x9c, 0x62, 0x0c, - 0x79, 0x8f, 0x08, 0xa2, 0x36, 0x8d, 0x57, 0xd5, 0xb7, 0xf5, 0x2d, 0x82, 0x6b, 0x6a, 0x4f, 0x64, - 0xbd, 0x1e, 0x6c, 0xb2, 0x78, 0xc7, 0x00, 0xda, 0x55, 0x61, 0x3c, 0xe9, 0x42, 0x49, 0x38, 0x56, - 0xb9, 0x65, 0x67, 0x9f, 0x26, 0x3b, 0x69, 0xbb, 0x72, 0xe9, 0xe0, 0x70, 0x0e, 0xfd, 0x7d, 0x38, - 0x97, 0xab, 0xa6, 0x7c, 0x58, 0xdf, 0x20, 0xb8, 0x9a, 0x9c, 0xf8, 0xd0, 0x17, 0x5b, 0x11, 0xde, - 0xff, 0x4c, 0xed, 0x53, 0x28, 0xa5, 0x64, 0xe3, 0x27, 0x49, 0x32, 0xda, 0x3d, 0x82, 0x89, 0x98, - 0xa0, 0x1f, 0x6c, 0x32, 0x49, 0xef, 0xe2, 0xc2, 0x58, 0xc5, 0xe9, 0x07, 0x37, 0x11, 0xe9, 0x4a, - 0x7e, 0x5f, 0xc2, 0xbf, 0xe0, 0x26, 0x96, 0xb9, 0xf5, 0x15, 0x82, 0x29, 0x05, 0x98, 0x4c, 0xd7, - 0x59, 0x07, 0x03, 0x17, 0x60, 0xc4, 0x0d, 0x29, 0x11, 0x2c, 0x54, 0xc1, 0x8f, 0x56, 0xa3, 0x21, - 0x9e, 0x85, 0x51, 0xb5, 0x65, 0x8b, 0xf0, 0xad, 0xc2, 0x45, 0xb5, 0x76, 0x49, 0x4e, 0xbc, 0x4d, - 0xf8, 0x16, 0x9e, 0x81, 0x61, 0xce, 0xda, 0xa1, 0x4b, 0x0b, 0x79, 0xb5, 0x62, 0x46, 0xd2, 0x5d, - 0xbd, 0xed, 0x37, 0x3d, 0x1a, 0x16, 0x86, 0xb4, 0x3b, 0x33, 0xb4, 0x76, 0xe1, 0xb2, 0x91, 0xc5, - 0xa3, 0x31, 0xad, 0xf7, 0x0d, 0x86, 0x54, 0x41, 0x11, 0x1b, 0xab, 0x2c, 0x9c, 0x2d, 0x42, 0x3a, - 0xa6, 0x44, 0x02, 0x14, 0x2f, 0xb9, 0x26, 0x0f, 0xf2, 0x0e, 0xe1, 0xdb, 0xe6, 0x9a, 0xaa, 0x6f, - 0xcb, 0x05, 0x1c, 0x23, 0xf3, 0x18, 0xfa, 0x5d, 0x80, 0x18, 0x3a, 0x4a, 0x40, 0xff, 0xd8, 0x5a, - 0xf9, 0xd1, 0x08, 0x97, 0x5b, 0xeb, 0x70, 0x3d, 0x95, 0xf5, 0xf8, 0x6e, 0x0f, 0x7c, 0x5f, 0xac, - 0x8a, 0x29, 0x5a, 0x91, 0x2b, 0x53, 0x5b, 0x8c, 0xa3, 0xec, 0xe2, 0x72, 0x0f, 0xae, 0xc4, 0x31, - 0xca, 0x04, 0xc5, 0xe6, 0xa9, 0x2c, 0xa2, 0x74, 0x16, 0xad, 0xaf, 0x11, 0x4c, 0x3e, 0xa0, 0x6e, - 0xd8, 0x69, 0x09, 0xea, 0x2d, 0x07, 0x7c, 0x87, 0x86, 0x52, 0x41, 0x59, 0xa1, 0x8d, 0xad, 0xfa, - 0x96, 0x98, 0x7e, 0xd0, 0x6a, 0x0b, 0x73, 0x44, 0xf4, 0x00, 0xcf, 0xc1, 0x18, 0x6b, 0x8b, 0x56, - 0x5b, 0xd4, 0x54, 0xed, 0xd0, 0x47, 0x04, 0xf4, 0xd4, 0x03, 0x22, 0x08, 0x2e, 0xc3, 0x95, 0x84, - 0x41, 0x8d, 0xf0, 0x1a, 0x17, 0xa1, 0x1f, 0x34, 0xcc, 0x99, 0xc1, 0x27, 0xa6, 0xcb, 0xfc, 0xa1, - 0x5a, 0xb9, 0x9f, 0xff, 0xeb, 0xbb, 0xb9, 0x9c, 0xf5, 0x0f, 0x82, 0xa9, 0x53, 0xbc, 0x38, 0x5e, - 0x86, 0x11, 0xa2, 0x3f, 0x4d, 0xb6, 0xe6, 0xcf, 0xca, 0xd6, 0xa9, 0xad, 0xd5, 0x68, 0x1f, 0xde, - 0x88, 0x19, 0x37, 0x59, 0x83, 0x17, 0x2e, 0x28, 0x37, 0xaf, 0xd8, 0xba, 0x93, 0xd8, 0xb2, 0x93, - 0xd8, 0xaa, 0x79, 0x44, 0x8e, 0x34, 0xa9, 0xb5, 0xa7, 0x34, 0x10, 0x26, 0xe3, 0x26, 0xbc, 0x0d, - 0xd6, 0xe0, 0xf8, 0x26, 0x8c, 0x1b, 0x6f, 0x34, 0x0c, 0x59, 0x68, 0x04, 0x30, 0x08, 0x6b, 0x72, - 0x0a, 0xcf, 0xc3, 0x64, 0xab, 0x49, 0xfc, 0x40, 0xd0, 0xdd, 0xc8, 0x4a, 0xc7, 0x3e, 0x11, 0x4f, - 0x2b, 0x43, 0x1d, 0x77, 0xe5, 0x70, 0x0c, 0x86, 0x54, 0x1a, 0xf1, 0x8f, 0x28, 0x5d, 0x99, 0xf0, - 0x1b, 0x67, 0x05, 0x7b, 0x6e, 0x4f, 0x29, 0x96, 0xcf, 0xdd, 0x96, 0x55, 0xd9, 0xad, 0xd7, 0x3f, - 0xfb, 0xf5, 0xcf, 0x2f, 0x2f, 0xdc, 0xc6, 0x0b, 0x5d, 0x9d, 0x5b, 0x5e, 0x15, 0xe7, 0x93, 0xd3, - 0xc7, 0x78, 0x0f, 0xff, 0x80, 0xe0, 0x72, 0x57, 0xb5, 0xc3, 0x77, 0x7a, 0x32, 0x4e, 0x74, 0xae, - 0xe2, 0x9b, 0x7d, 0x11, 0xed, 0xaa, 0xa5, 0xd6, 0x1d, 0xc5, 0xf6, 0x55, 0x7c, 0xab, 0x8b, 0x6d, - 0xc4, 0x93, 0x4b, 0xca, 0xaa, 0xf4, 0xed, 0xe1, 0x9f, 0x91, 0xe9, 0xd8, 0xe9, 0x3e, 0x88, 0x2b, - 0xe7, 0xa2, 0x67, 0xbe, 0x1e, 0x8a, 0x77, 0x07, 0xda, 0x63, 0xe8, 0x96, 0x15, 0xdd, 0x25, 0xbc, - 0x98, 0xfd, 0xd0, 0xca, 0x52, 0xf7, 0x73, 0x04, 0x79, 0x19, 0xf4, 0x80, 0x82, 0x2e, 0xf6, 0x10, - 0xf4, 0xa4, 0x0a, 0x5b, 0xf3, 0x8a, 0xd4, 0x4d, 0x3c, 0x97, 0xa1, 0xa1, 0x47, 0x13, 0xf2, 0x3d, - 0x86, 0x21, 0x55, 0x44, 0xf1, 0x8c, 0xad, 0xdf, 0x66, 0x76, 0xf4, 0x70, 0xb3, 0xd7, 0xe4, 0xc3, - 0xad, 0x78, 0xbb, 0x27, 0x68, 0x5c, 0x11, 0xad, 0x92, 0x42, 0x2d, 0xe0, 0x99, 0x4c, 0x54, 0x8e, - 0x7f, 0x41, 0x70, 0x2d, 0x2a, 0x67, 0x5d, 0xe7, 0xfb, 0x79, 0xef, 0xc3, 0x6b, 0x3d, 0x09, 0x26, - 0xab, 0xa7, 0xb5, 0xae, 0x38, 0xae, 0xe2, 0xe5, 0x4c, 0x8e, 0xaa, 0xa8, 0x3a, 0xf5, 0x4e, 0xed, - 0x74, 0xd2, 0xb2, 0xd2, 0xf8, 0xcc, 0xb4, 0xe5, 0x28, 0x9c, 0xe7, 0xb8, 0x23, 0x03, 0x92, 0x7f, - 0x4b, 0x91, 0x2f, 0x63, 0xa7, 0x17, 0x79, 0x95, 0xdd, 0x44, 0x9a, 0x7f, 0x42, 0x30, 0xa1, 0x9a, - 0xce, 0x4a, 0xe7, 0x3f, 0xca, 0x5d, 0xe9, 0xeb, 0x56, 0xa7, 0x1a, 0xdc, 0x39, 0x57, 0x44, 0xb5, - 0xba, 0x2c, 0x6d, 0xbf, 0x47, 0x30, 0x11, 0xbd, 0x89, 0xf4, 0x53, 0x1c, 0x2f, 0xf5, 0x20, 0x9c, - 0x7c, 0xb0, 0x17, 0xef, 0xf5, 0x45, 0xf3, 0x54, 0x4b, 0x3f, 0x87, 0x68, 0xf7, 0x79, 0x50, 0xd4, - 0xf7, 0x56, 0x1e, 0xed, 0xff, 0x51, 0xca, 0x3d, 0x3b, 0x2a, 0xa1, 0xfd, 0xa3, 0x12, 0x3a, 0x38, - 0x2a, 0xa1, 0xdf, 0x8f, 0x4a, 0xe8, 0x8b, 0xe3, 0x52, 0xee, 0xe0, 0xb8, 0x94, 0xfb, 0xed, 0xb8, - 0x94, 0xfb, 0xe8, 0x7e, 0xc3, 0x17, 0x5b, 0xed, 0xba, 0x64, 0xe2, 0x70, 0x37, 0x14, 0x4d, 0x52, - 0xe7, 0x8e, 0x2e, 0x26, 0xef, 0x51, 0xb1, 0xc3, 0xc2, 0xc7, 0xce, 0x6e, 0x8c, 0x27, 0x3b, 0x48, - 0x18, 0x90, 0xa6, 0xfe, 0xa7, 0xaa, 0x0f, 0xab, 0xdb, 0x78, 0xf7, 0xdf, 0x00, 0x00, 0x00, 0xff, - 0xff, 0x35, 0x86, 0x2d, 0xca, 0xcc, 0x0d, 0x00, 0x00, + 0x14, 0xf6, 0xb4, 0x4e, 0xd2, 0xbc, 0xa4, 0x49, 0x3a, 0xa4, 0xa9, 0xeb, 0x14, 0xa7, 0x5d, 0x4a, + 0xf3, 0xab, 0x78, 0x6b, 0x27, 0x14, 0xa9, 0xe2, 0x92, 0xa4, 0x81, 0x06, 0x05, 0x28, 0xee, 0x01, + 0x09, 0x15, 0x59, 0xe3, 0xf5, 0xc4, 0x5e, 0xd5, 0xd9, 0x71, 0x77, 0xc6, 0x4d, 0x2c, 0x14, 0x0e, + 0x9c, 0x38, 0x56, 0x02, 0x24, 0x04, 0x17, 0x4e, 0x50, 0x71, 0x40, 0xe2, 0x08, 0x7f, 0x41, 0x0e, + 0x1c, 0x22, 0x71, 0xe1, 0x54, 0x41, 0xc2, 0x01, 0x71, 0xe7, 0x8e, 0x76, 0x66, 0x76, 0xb3, 0x6b, + 0xaf, 0x63, 0x3b, 0x1c, 0xb8, 0xed, 0xcc, 0xbc, 0xf7, 0xbe, 0xef, 0xbd, 0x37, 0xf3, 0xde, 0x5b, + 0x30, 0x38, 0xb5, 0x5c, 0x2a, 0x4c, 0x8b, 0x6d, 0xd7, 0x1b, 0x82, 0x9a, 0x4f, 0x72, 0x25, 0x2a, + 0x48, 0xce, 0x7c, 0xdc, 0xa0, 0x6e, 0x33, 0x5b, 0x77, 0x99, 0x60, 0x78, 0x4a, 0xc9, 0x64, 0xb5, + 0x4c, 0x56, 0xcb, 0xa4, 0x27, 0x2b, 0xac, 0xc2, 0xa4, 0x88, 0xe9, 0x7d, 0x29, 0xe9, 0x74, 0x27, + 0x8b, 0xa2, 0x59, 0xa7, 0x5c, 0xcb, 0x4c, 0x57, 0x18, 0xab, 0xd4, 0xa8, 0x29, 0x57, 0xa5, 0xc6, + 0x96, 0x49, 0xb7, 0xeb, 0x42, 0xc3, 0xa5, 0xaf, 0xe8, 0x43, 0x52, 0xb7, 0x4d, 0xe2, 0x38, 0x4c, + 0x10, 0x61, 0x33, 0xc7, 0x57, 0x7d, 0xc9, 0x62, 0x7c, 0x9b, 0x71, 0xb3, 0x44, 0x38, 0x35, 0x49, + 0xc9, 0xb2, 0x03, 0x00, 0x6f, 0xa1, 0x85, 0x16, 0xc2, 0x42, 0xd2, 0x95, 0x40, 0xaa, 0x4e, 0x2a, + 0xb6, 0x23, 0x2d, 0x2a, 0x59, 0xe3, 0x43, 0x48, 0xbf, 0xe7, 0x49, 0x3c, 0x90, 0xb4, 0xd7, 0x98, + 0x23, 0x5c, 0x62, 0x89, 0x02, 0x7d, 0xdc, 0xa0, 0x5c, 0xe0, 0x79, 0x98, 0xb0, 0xf4, 0x56, 0x91, + 0x94, 0xcb, 0x2e, 0xe5, 0x3c, 0x85, 0xae, 0xa2, 0xb9, 0xe1, 0xc2, 0xb8, 0xbf, 0xbf, 0xa2, 0xb6, + 0xf1, 0x24, 0x0c, 0x48, 0xa8, 0xd4, 0x99, 0xab, 0x68, 0x6e, 0xb4, 0xa0, 0x16, 0xc6, 0x22, 0xbc, + 0x20, 0xcd, 0xaf, 0x36, 0x37, 0x49, 0x89, 0xd6, 0x7c, 0xbb, 0x93, 0x30, 0x50, 0xf3, 0xd6, 0xda, + 0x98, 0x5a, 0x18, 0x6f, 0xc1, 0x8b, 0x5a, 0x78, 0x2d, 0x6a, 0xbc, 0x7f, 0x3a, 0x86, 0x09, 0x93, + 0x81, 0xad, 0x32, 0xdd, 0x28, 0xfb, 0x26, 0x2e, 0xc1, 0x90, 0xc5, 0xca, 0xb4, 0x68, 0x97, 0xa5, + 0x66, 0xb2, 0x30, 0x68, 0xc9, 0x73, 0x23, 0x07, 0xd3, 0xb1, 0x81, 0xe0, 0x75, 0xe6, 0x70, 0x8a, + 0x31, 0x24, 0xcb, 0x44, 0x10, 0xa9, 0x34, 0x5a, 0x90, 0xdf, 0xc6, 0x57, 0x08, 0x2e, 0x4b, 0x1d, + 0x5f, 0x7a, 0xc3, 0xd9, 0x62, 0x81, 0x46, 0x1f, 0xb1, 0x2b, 0xc0, 0x68, 0xd8, 0x84, 0x0c, 0xe1, + 0x48, 0xfe, 0x7a, 0x36, 0xfe, 0xe6, 0x65, 0xc3, 0xb2, 0xab, 0xe7, 0x0e, 0x9e, 0xcf, 0xa0, 0xbf, + 0x9f, 0xcf, 0x24, 0x0a, 0x11, 0x1b, 0xc6, 0x97, 0x08, 0x2e, 0x85, 0x37, 0xde, 0xb7, 0x45, 0xd5, + 0xc7, 0xfb, 0x9f, 0xa9, 0x7d, 0x0c, 0x99, 0x48, 0xd8, 0xf8, 0x71, 0x92, 0x74, 0xec, 0x1e, 0xc2, + 0x58, 0x40, 0xd0, 0x76, 0xb6, 0x98, 0x47, 0xef, 0xec, 0xdc, 0x48, 0xde, 0xec, 0x05, 0x37, 0xe4, + 0xe9, 0x6a, 0x72, 0xdf, 0x83, 0x3f, 0x6f, 0x85, 0x8e, 0xb9, 0xf1, 0x39, 0x82, 0x09, 0x09, 0x18, + 0x4e, 0x57, 0xa7, 0x8b, 0x81, 0x53, 0x30, 0x64, 0xb9, 0x94, 0x08, 0xe6, 0x4a, 0xe7, 0x87, 0x0b, + 0xfe, 0x12, 0x4f, 0xc3, 0xb0, 0x54, 0xa9, 0x12, 0x5e, 0x4d, 0x9d, 0x95, 0x67, 0xe7, 0xbc, 0x8d, + 0x7b, 0x84, 0x57, 0xf1, 0x14, 0x0c, 0x72, 0xd6, 0x70, 0x2d, 0x9a, 0x4a, 0xca, 0x13, 0xbd, 0xf2, + 0xcc, 0x95, 0x1a, 0x76, 0xad, 0x4c, 0xdd, 0xd4, 0x80, 0x32, 0xa7, 0x97, 0xc6, 0x2e, 0x5c, 0xd0, + 0x61, 0x29, 0xd3, 0x80, 0xd6, 0xbb, 0x1a, 0xc3, 0x8b, 0x82, 0x24, 0x36, 0x92, 0x9f, 0xeb, 0x1c, + 0x84, 0xa8, 0x4f, 0xa1, 0x04, 0x48, 0x5e, 0xde, 0x99, 0x77, 0x91, 0x77, 0x08, 0xdf, 0xd6, 0xcf, + 0x54, 0x7e, 0x1b, 0x16, 0xe0, 0x00, 0x99, 0x07, 0xd0, 0x6f, 0x03, 0x04, 0xd0, 0x7e, 0x02, 0x7a, + 0xc7, 0x56, 0x91, 0x1f, 0xf6, 0x71, 0xb9, 0xb1, 0x01, 0x57, 0x22, 0x59, 0x0f, 0xde, 0x76, 0xdf, + 0xef, 0xc5, 0xc8, 0xeb, 0xa2, 0xe5, 0x9b, 0xd2, 0xb5, 0x45, 0x1b, 0x8a, 0x2f, 0x2e, 0xcb, 0x70, + 0x31, 0xf0, 0xd1, 0x4b, 0x50, 0x20, 0x1e, 0xc9, 0x22, 0x8a, 0x66, 0xd1, 0xf8, 0x02, 0xc1, 0xf8, + 0x5d, 0x6a, 0xb9, 0xcd, 0xba, 0xa0, 0xe5, 0x15, 0x87, 0xef, 0x50, 0xd7, 0x8b, 0xa0, 0x57, 0xcd, + 0xb5, 0xac, 0xfc, 0xf6, 0x30, 0x6d, 0xa7, 0xde, 0x10, 0xfa, 0x8a, 0xa8, 0x05, 0x9e, 0x81, 0x11, + 0xd6, 0x10, 0xf5, 0x86, 0x28, 0xca, 0xda, 0xa1, 0xae, 0x08, 0xa8, 0xad, 0xbb, 0x44, 0x10, 0x9c, + 0x83, 0x8b, 0x21, 0x81, 0x22, 0xe1, 0x45, 0x2e, 0x5c, 0xdb, 0xa9, 0xe8, 0x3b, 0x83, 0x8f, 0x45, + 0x57, 0xf8, 0x03, 0x79, 0x72, 0x27, 0xf9, 0xd7, 0x37, 0x33, 0x09, 0xe3, 0x1f, 0x04, 0x13, 0x2d, + 0xbc, 0x38, 0x5e, 0x81, 0x21, 0xa2, 0x3e, 0x75, 0xb6, 0x66, 0x3b, 0x65, 0xab, 0x45, 0xb5, 0xe0, + 0xeb, 0xe1, 0xcd, 0x80, 0x71, 0x8d, 0x55, 0x78, 0xea, 0x8c, 0x34, 0xf3, 0x72, 0x56, 0x35, 0x94, + 0xac, 0xd7, 0x50, 0xb2, 0xb2, 0xd1, 0xf8, 0x86, 0x14, 0xa9, 0xf5, 0x27, 0xd4, 0x11, 0x3a, 0xe3, + 0xda, 0xbd, 0x4d, 0x56, 0xe1, 0xf8, 0x1a, 0x8c, 0x6a, 0x6b, 0xd4, 0x75, 0x99, 0xab, 0x03, 0xa0, + 0x11, 0xd6, 0xbd, 0x2d, 0x3c, 0x0b, 0xe3, 0xf5, 0x1a, 0xb1, 0x1d, 0x41, 0x77, 0x7d, 0x29, 0xe5, + 0xfb, 0x58, 0xb0, 0x2d, 0x05, 0xb5, 0xdf, 0x4f, 0x91, 0x2e, 0xd3, 0x7e, 0xea, 0xef, 0xd9, 0x5c, + 0x30, 0xb7, 0x79, 0x8a, 0x86, 0xf5, 0x06, 0xc0, 0x71, 0x37, 0xd4, 0x75, 0xed, 0x46, 0xc4, 0x53, + 0x35, 0x05, 0xf8, 0xae, 0xde, 0x27, 0x15, 0xaa, 0x61, 0x0a, 0x21, 0x4d, 0xe3, 0x27, 0xd4, 0x72, + 0xb1, 0x03, 0x4a, 0xfa, 0x82, 0xdd, 0x87, 0x21, 0xea, 0x08, 0xd7, 0xa6, 0x7e, 0x5a, 0x6e, 0x75, + 0xab, 0x62, 0xf2, 0x8e, 0x2a, 0x2b, 0xeb, 0x8e, 0x70, 0x9b, 0x3a, 0xb4, 0xbe, 0x19, 0xfc, 0x66, + 0x0c, 0xf5, 0xd9, 0xae, 0xd4, 0x15, 0x9d, 0x30, 0xf7, 0xfc, 0xd7, 0xe7, 0x61, 0x40, 0x72, 0xc7, + 0xdf, 0xa3, 0x68, 0xa1, 0xc7, 0xaf, 0x76, 0x22, 0x79, 0x62, 0x8b, 0x4e, 0xe7, 0x4e, 0x54, 0x8b, + 0x6b, 0x94, 0xc6, 0xad, 0x4f, 0x7e, 0xfd, 0xf3, 0xb3, 0x33, 0x0b, 0x78, 0xae, 0x6d, 0x68, 0xf2, + 0x2a, 0x8f, 0xf9, 0x51, 0x6b, 0x42, 0xf7, 0xf0, 0x77, 0x08, 0x2e, 0xb4, 0x35, 0x0f, 0x7c, 0xb3, + 0x2b, 0xe3, 0xd0, 0x20, 0x90, 0xbe, 0xdd, 0x13, 0xd1, 0xb6, 0xd6, 0x64, 0xdc, 0x94, 0x6c, 0x6f, + 0xe0, 0xeb, 0x6d, 0x6c, 0x7d, 0x9e, 0xdc, 0xa3, 0x2c, 0x3b, 0xc9, 0x1e, 0xfe, 0x11, 0xe9, 0x01, + 0x28, 0x3a, 0x56, 0xe0, 0xfc, 0x89, 0xe8, 0xb1, 0xc3, 0x58, 0x7a, 0xa9, 0x2f, 0x1d, 0x4d, 0x37, + 0x27, 0xe9, 0x2e, 0xe2, 0xf9, 0xf8, 0x19, 0x37, 0x2e, 0xba, 0x9f, 0x22, 0x48, 0x7a, 0x4e, 0xf7, + 0x19, 0xd0, 0xf9, 0x2e, 0x01, 0x3d, 0x6e, 0x6a, 0xc6, 0xac, 0x24, 0x75, 0x0d, 0xcf, 0xc4, 0xc4, + 0xb0, 0x4c, 0x43, 0xe1, 0x7b, 0x04, 0x03, 0xb2, 0x27, 0xe1, 0xa9, 0xac, 0x1a, 0x8b, 0xb3, 0xfe, + 0xcc, 0x9c, 0x5d, 0xf7, 0x66, 0xe6, 0xf4, 0x42, 0x57, 0xd0, 0xa0, 0xc1, 0x18, 0x19, 0x89, 0x9a, + 0xc2, 0x53, 0xb1, 0xa8, 0x1c, 0xff, 0x82, 0xe0, 0xb2, 0xdf, 0x1d, 0xda, 0xee, 0xf7, 0x69, 0xdf, + 0xc3, 0x2b, 0x5d, 0x09, 0x86, 0x9b, 0x91, 0xb1, 0x21, 0x39, 0xae, 0xe1, 0x95, 0x58, 0x8e, 0xb2, + 0x47, 0x99, 0xa5, 0x66, 0xb1, 0x35, 0x69, 0x71, 0x69, 0x7c, 0xa6, 0xa7, 0x1c, 0xdf, 0x9d, 0x53, + 0xbc, 0x91, 0x3e, 0xc9, 0xbf, 0x26, 0xc9, 0xe7, 0xb0, 0xd9, 0x8d, 0xbc, 0xcc, 0x6e, 0x28, 0xcd, + 0x3f, 0x20, 0x18, 0x93, 0x3d, 0x7c, 0xb5, 0xf9, 0x1f, 0xc3, 0x9d, 0xef, 0xe9, 0x55, 0x47, 0xe6, + 0x85, 0x13, 0x9e, 0x88, 0x9c, 0x1c, 0xe2, 0x62, 0xfb, 0x2d, 0x82, 0x31, 0x7f, 0xc4, 0x54, 0x7f, + 0x36, 0x78, 0xb1, 0x0b, 0xe1, 0xf0, 0xff, 0x4f, 0x7a, 0xb9, 0x27, 0x9a, 0x2d, 0x13, 0xd2, 0x09, + 0x44, 0xdb, 0xef, 0x83, 0xa4, 0xbe, 0x87, 0x7f, 0x46, 0x30, 0xde, 0xd2, 0x97, 0xf0, 0x52, 0x4f, + 0xe0, 0xd1, 0xc6, 0xda, 0x23, 0xe3, 0x96, 0xd6, 0x67, 0xbc, 0x2e, 0x19, 0xdf, 0xc6, 0xcb, 0x9d, + 0x19, 0x57, 0x95, 0x4a, 0x4c, 0x94, 0x57, 0x1f, 0xee, 0xff, 0x91, 0x49, 0x3c, 0x3b, 0xcc, 0xa0, + 0xfd, 0xc3, 0x0c, 0x3a, 0x38, 0xcc, 0xa0, 0xdf, 0x0f, 0x33, 0xe8, 0xe9, 0x51, 0x26, 0x71, 0x70, + 0x94, 0x49, 0xfc, 0x76, 0x94, 0x49, 0x7c, 0x70, 0xa7, 0x62, 0x8b, 0x6a, 0xa3, 0xe4, 0x91, 0x32, + 0xb9, 0xe5, 0x8a, 0x1a, 0x29, 0x71, 0x53, 0x55, 0xc2, 0x77, 0xa8, 0xd8, 0x61, 0xee, 0x23, 0x73, + 0x37, 0x80, 0xf6, 0xa6, 0x09, 0xd7, 0x21, 0x35, 0xf5, 0x2f, 0x5e, 0x1a, 0x94, 0xa5, 0x64, 0xe9, + 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x29, 0x89, 0x0c, 0x2d, 0x04, 0x10, 0x00, 0x00, } func (this *QuerySecretContractRequest) Equal(that interface{}) bool { @@ -1116,6 +1210,65 @@ func (this *QueryCodeHashResponse) Equal(that interface{}) bool { } return true } +func (this *QueryContractHistoryRequest) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*QueryContractHistoryRequest) + if !ok { + that2, ok := that.(QueryContractHistoryRequest) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.ContractAddress != that1.ContractAddress { + return false + } + if !this.Pagination.Equal(that1.Pagination) { + return false + } + return true +} +func (this *QueryContractHistoryResponse) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*QueryContractHistoryResponse) + if !ok { + that2, ok := that.(QueryContractHistoryResponse) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if len(this.Entries) != len(that1.Entries) { + return false + } + for i := range this.Entries { + if !this.Entries[i].Equal(&that1.Entries[i]) { + return false + } + } + if !this.Pagination.Equal(that1.Pagination) { + return false + } + return true +} // Reference imports to suppress errors if they are not otherwise used. var _ context.Context @@ -1147,6 +1300,8 @@ type QueryClient interface { LabelByAddress(ctx context.Context, in *QueryByContractAddressRequest, opts ...grpc.CallOption) (*QueryContractLabelResponse, error) // Query contract address by label AddressByLabel(ctx context.Context, in *QueryByLabelRequest, opts ...grpc.CallOption) (*QueryContractAddressResponse, error) + // ContractHistory gets the contract code history + ContractHistory(ctx context.Context, in *QueryContractHistoryRequest, opts ...grpc.CallOption) (*QueryContractHistoryResponse, error) } type queryClient struct { @@ -1238,6 +1393,15 @@ func (c *queryClient) AddressByLabel(ctx context.Context, in *QueryByLabelReques return out, nil } +func (c *queryClient) ContractHistory(ctx context.Context, in *QueryContractHistoryRequest, opts ...grpc.CallOption) (*QueryContractHistoryResponse, error) { + out := new(QueryContractHistoryResponse) + err := c.cc.Invoke(ctx, "/secret.compute.v1beta1.Query/ContractHistory", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // QueryServer is the server API for Query service. type QueryServer interface { // Query contract info by address @@ -1258,6 +1422,8 @@ type QueryServer interface { LabelByAddress(context.Context, *QueryByContractAddressRequest) (*QueryContractLabelResponse, error) // Query contract address by label AddressByLabel(context.Context, *QueryByLabelRequest) (*QueryContractAddressResponse, error) + // ContractHistory gets the contract code history + ContractHistory(context.Context, *QueryContractHistoryRequest) (*QueryContractHistoryResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. @@ -1291,6 +1457,9 @@ func (*UnimplementedQueryServer) LabelByAddress(ctx context.Context, req *QueryB func (*UnimplementedQueryServer) AddressByLabel(ctx context.Context, req *QueryByLabelRequest) (*QueryContractAddressResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method AddressByLabel not implemented") } +func (*UnimplementedQueryServer) ContractHistory(ctx context.Context, req *QueryContractHistoryRequest) (*QueryContractHistoryResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ContractHistory not implemented") +} func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) @@ -1458,6 +1627,24 @@ func _Query_AddressByLabel_Handler(srv interface{}, ctx context.Context, dec fun return interceptor(ctx, in, info, handler) } +func _Query_ContractHistory_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryContractHistoryRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).ContractHistory(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/secret.compute.v1beta1.Query/ContractHistory", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).ContractHistory(ctx, req.(*QueryContractHistoryRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "secret.compute.v1beta1.Query", HandlerType: (*QueryServer)(nil), @@ -1498,6 +1685,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "AddressByLabel", Handler: _Query_AddressByLabel_Handler, }, + { + MethodName: "ContractHistory", + Handler: _Query_ContractHistory_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "secret/compute/v1beta1/query.proto", @@ -2120,6 +2311,97 @@ func (m *DecryptedAnswers) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *QueryContractHistoryRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryContractHistoryRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryContractHistoryRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.ContractAddress) > 0 { + i -= len(m.ContractAddress) + copy(dAtA[i:], m.ContractAddress) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ContractAddress))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryContractHistoryResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryContractHistoryResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryContractHistoryResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Entries) > 0 { + for iNdEx := len(m.Entries) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Entries[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { offset -= sovQuery(v) base := offset @@ -2401,6 +2683,42 @@ func (m *DecryptedAnswers) Size() (n int) { return n } +func (m *QueryContractHistoryRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ContractAddress) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryContractHistoryResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Entries) > 0 { + for _, e := range m.Entries { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -4167,6 +4485,244 @@ func (m *DecryptedAnswers) Unmarshal(dAtA []byte) error { } return nil } +func (m *QueryContractHistoryRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryContractHistoryRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryContractHistoryRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageRequest{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryContractHistoryResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryContractHistoryResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryContractHistoryResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Entries", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Entries = append(m.Entries, ContractCodeHistoryEntry{}) + if err := m.Entries[len(m.Entries)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageResponse{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipQuery(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/compute/internal/types/query.pb.gw.go b/x/compute/internal/types/query.pb.gw.go index aa3c49fef..687b5f4f9 100644 --- a/x/compute/internal/types/query.pb.gw.go +++ b/x/compute/internal/types/query.pb.gw.go @@ -500,6 +500,78 @@ func local_request_Query_AddressByLabel_0(ctx context.Context, marshaler runtime } +var ( + filter_Query_ContractHistory_0 = &utilities.DoubleArray{Encoding: map[string]int{"contract_address": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +) + +func request_Query_ContractHistory_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryContractHistoryRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["contract_address"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "contract_address") + } + + protoReq.ContractAddress, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "contract_address", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_ContractHistory_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ContractHistory(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_ContractHistory_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryContractHistoryRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["contract_address"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "contract_address") + } + + protoReq.ContractAddress, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "contract_address", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_ContractHistory_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ContractHistory(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterQueryHandlerServer registers the http handlers for service Query to "mux". // UnaryRPC :call QueryServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -686,6 +758,26 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_ContractHistory_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_ContractHistory_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_ContractHistory_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -907,6 +999,26 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_ContractHistory_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_ContractHistory_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_ContractHistory_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -928,6 +1040,8 @@ var ( pattern_Query_LabelByAddress_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"compute", "v1beta1", "label", "contract_address"}, "", runtime.AssumeColonVerbOpt(true))) pattern_Query_AddressByLabel_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"compute", "v1beta1", "contract_address", "label"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_ContractHistory_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"compute", "v1beta1", "contract_history", "contract_address"}, "", runtime.AssumeColonVerbOpt(true))) ) var ( @@ -948,4 +1062,6 @@ var ( forward_Query_LabelByAddress_0 = runtime.ForwardResponseMessage forward_Query_AddressByLabel_0 = runtime.ForwardResponseMessage + + forward_Query_ContractHistory_0 = runtime.ForwardResponseMessage ) From bd2006a10fd0c6e6366eca7b3a11e7cd6a535c35 Mon Sep 17 00:00:00 2001 From: Itzik Grossman Date: Mon, 22 May 2023 17:21:12 +0300 Subject: [PATCH 007/164] Added migrate flow and admin proof for contract upgrades. Up next: migrate contract key & update validation function on exec --- cosmwasm/enclaves/execute/Enclave.edl | 18 ++ cosmwasm/enclaves/ffi-types/src/lib.rs | 5 +- cosmwasm/enclaves/ffi-types/src/types.rs | 13 ++ .../src/contract_operations.rs | 162 +++++++++++++++++- .../contract-engine/src/cosmwasm_config.rs | 5 + .../contract-engine/src/external/ecalls.rs | 88 +++++++++- .../contract-engine/src/external/results.rs | 39 ++++- .../shared/contract-engine/src/wasm3/mod.rs | 66 +++++++ cosmwasm/packages/sgx-vm/src/calls.rs | 17 ++ cosmwasm/packages/sgx-vm/src/instance.rs | 12 ++ cosmwasm/packages/sgx-vm/src/lib.rs | 2 +- cosmwasm/packages/sgx-vm/src/wasmi/imports.rs | 22 ++- cosmwasm/packages/sgx-vm/src/wasmi/results.rs | 27 ++- cosmwasm/packages/sgx-vm/src/wasmi/wrapper.rs | 66 ++++++- go-cosmwasm/api/lib.go | 54 ++++++ go-cosmwasm/lib.go | 125 ++++++-------- go-cosmwasm/src/lib.rs | 79 ++++++++- go-cosmwasm/types/types.go | 1 - proto/secret/compute/v1beta1/types.proto | 4 +- x/compute/internal/keeper/keeper.go | 20 ++- x/compute/internal/types/types.go | 2 +- 21 files changed, 725 insertions(+), 102 deletions(-) diff --git a/cosmwasm/enclaves/execute/Enclave.edl b/cosmwasm/enclaves/execute/Enclave.edl index b6d9a6e8e..7aba2a93b 100644 --- a/cosmwasm/enclaves/execute/Enclave.edl +++ b/cosmwasm/enclaves/execute/Enclave.edl @@ -106,6 +106,24 @@ enclave { uintptr_t msg_len ); + public HandleResult ecall_migrate( + Ctx context, + uint64_t gas_limit, + [out] uint64_t* used_gas, + [in, count=contract_len] const uint8_t* contract, + uintptr_t contract_len, + [in, count=env_len] const uint8_t* env, + uintptr_t env_len, + [in, count=msg_len] const uint8_t* msg, + uintptr_t msg_len, + [in, count=sig_info_len] const uint8_t* sig_info, + uintptr_t sig_info_len, + [in, count=admin_len] const uint8_t* admin, + uintptr_t admin_len, + [in, count=admin_proof_len] const uint8_t* admin_proof, + uintptr_t admin_proof_len + ); + public HealthCheckResult ecall_health_check(); public uint32_t ecall_run_tests(); diff --git a/cosmwasm/enclaves/ffi-types/src/lib.rs b/cosmwasm/enclaves/ffi-types/src/lib.rs index 9c7cd5633..4990ef72a 100644 --- a/cosmwasm/enclaves/ffi-types/src/lib.rs +++ b/cosmwasm/enclaves/ffi-types/src/lib.rs @@ -4,8 +4,9 @@ mod types; pub use types::{ - Ctx, EnclaveBuffer, EnclaveError, HandleResult, HealthCheckResult, InitResult, NodeAuthResult, - OcallReturn, QueryResult, RuntimeConfiguration, UntrustedVmError, UserSpaceBuffer, + Ctx, EnclaveBuffer, EnclaveError, HandleResult, HealthCheckResult, InitResult, MigrateResult, + NodeAuthResult, OcallReturn, QueryResult, RuntimeConfiguration, UntrustedVmError, + UserSpaceBuffer, }; // On input, the encrypted seed is expected to contain 3 values: diff --git a/cosmwasm/enclaves/ffi-types/src/types.rs b/cosmwasm/enclaves/ffi-types/src/types.rs index 602b0dcd6..509851e9b 100644 --- a/cosmwasm/enclaves/ffi-types/src/types.rs +++ b/cosmwasm/enclaves/ffi-types/src/types.rs @@ -302,6 +302,7 @@ pub enum InitResult { output: UserSpaceBuffer, /// The contract_key for this contract. contract_key: [u8; 64], + admin_proof: [u8; 32], }, Failure { /// The error that happened in the enclave @@ -323,6 +324,18 @@ pub enum HandleResult { }, } +#[repr(C)] +pub enum MigrateResult { + Success { + /// A pointer to the output of the calculation + output: UserSpaceBuffer, + }, + Failure { + /// The error that happened in the enclave + err: EnclaveError, + }, +} + /// This struct is returned from ecall_query. /// cbindgen:prefix-with-name #[repr(C)] diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index fa3643d4d..728dff4c6 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -9,7 +9,7 @@ use cw_types_v010::encoding::Binary; use cw_types_v010::types::CanonicalAddr; use enclave_cosmos_types::types::{ContractCode, HandleType, SigInfo}; -use enclave_crypto::Ed25519PublicKey; +use enclave_crypto::{sha_256, Ed25519PublicKey}; use enclave_ffi_types::{Ctx, EnclaveError}; use log::*; @@ -19,7 +19,7 @@ use crate::cosmwasm_config::ContractOperation; use crate::contract_validation::verify_block_info; use crate::contract_validation::{ReplyParams, ValidatedMessage}; -use crate::external::results::{HandleSuccess, InitSuccess, QuerySuccess}; +use crate::external::results::{HandleSuccess, InitSuccess, MigrateSuccess, QuerySuccess}; use crate::message::{is_ibc_msg, parse_message}; use crate::types::ParsedMessage; @@ -35,7 +35,7 @@ use super::contract_validation::{ }; use super::gas::WasmCosts; use super::io::{ - post_process_output, finalize_raw_output, manipulate_callback_sig_for_plaintext, + finalize_raw_output, manipulate_callback_sig_for_plaintext, post_process_output, set_all_logs_to_plaintext, }; use super::types::{IoNonce, SecretMessage}; @@ -55,6 +55,13 @@ we need to allocate memory regions inside the VM's instance and copy `env` & `msg` into those memory regions inside the VM's instance. */ +fn generate_admin_signature(admin: &[u8], code_hash: &[u8]) -> [u8; enclave_crypto::HASH_SIZE] { + let mut data_to_hash = vec![]; + data_to_hash.extend_from_slice(admin); + data_to_hash.extend_from_slice(code_hash); + sha_256(&data_to_hash) +} + pub fn init( context: Ctx, // need to pass this to read_db & write_db gas_limit: u64, // gas limit for this execution @@ -81,6 +88,8 @@ pub fn init( verify_block_info(&base_env)?; } + let admin_sig = generate_admin_signature(admin, &contract_hash); + // let duration = start.elapsed(); // trace!("Time elapsed in extract_base_env is: {:?}", duration); let query_depth = extract_query_depth(env)?; @@ -91,7 +100,6 @@ pub fn init( // trace!("Time elapsed in get_verification_paramsis: {:?}", duration); let canonical_contract_address = to_canonical(contract_address)?; - let canonical_sender_address = to_canonical(sender)?; let contract_key = generate_contract_key( @@ -190,6 +198,7 @@ pub fn init( Ok(InitSuccess { output, contract_key, + admin_proof: admin_sig, }) } @@ -220,6 +229,148 @@ fn to_canonical(contract_address: &BaseAddr) -> Result Result { + trace!("Starting init"); + + //let start = Instant::now(); + let contract_code = ContractCode::new(contract); + let contract_hash = contract_code.hash(); + // let duration = start.elapsed(); + // trace!("Time elapsed in ContractCode::new is: {:?}", duration); + + //let start = Instant::now(); + let base_env: BaseEnv = extract_base_env(env)?; + + #[cfg(feature = "light-client-validation")] + { + verify_block_info(&base_env)?; + } + + let admin_sig = generate_admin_signature(admin, &contract_hash); + + if &admin_sig != admin_proof { + error!("Failed to validate admin signature for migrate"); + } + + // let duration = start.elapsed(); + // trace!("Time elapsed in extract_base_env is: {:?}", duration); + let query_depth = extract_query_depth(env)?; + + //let start = Instant::now(); + let (sender, contract_address, block_height, sent_funds) = base_env.get_verification_params(); + // let duration = start.elapsed(); + // trace!("Time elapsed in get_verification_paramsis: {:?}", duration); + + let canonical_contract_address = to_canonical(contract_address)?; + let canonical_sender_address = to_canonical(sender)?; + + let contract_key = generate_contract_key( + &canonical_sender_address, + &block_height, + &contract_hash, + &canonical_contract_address, + )?; + + let parsed_sig_info: SigInfo = extract_sig_info(sig_info)?; + + let secret_msg = SecretMessage::from_slice(msg)?; + + //let start = Instant::now(); + verify_params( + &parsed_sig_info, + sent_funds, + &canonical_sender_address, + contract_address, + &secret_msg, + msg, + )?; + // let duration = start.elapsed(); + // trace!("Time elapsed in verify_params: {:?}", duration); + + //let start = Instant::now(); + let decrypted_msg = secret_msg.decrypt()?; + // let duration = start.elapsed(); + // trace!("Time elapsed in decrypt: {:?}", duration); + + //let start = Instant::now(); + let ValidatedMessage { + validated_msg, + reply_params, + } = validate_msg(&decrypted_msg, &contract_hash, None, None)?; + // let duration = start.elapsed(); + // trace!("Time elapsed in validate_msg: {:?}", duration); + + //let start = Instant::now(); + let mut engine = start_engine( + context, + gas_limit, + &contract_code, + &contract_key, + ContractOperation::Migrate, + query_depth, + secret_msg.nonce, + secret_msg.user_public_key, + base_env.0.block.time, + )?; + // let duration = start.elapsed(); + // trace!("Time elapsed in start_engine: {:?}", duration); + + let mut versioned_env = base_env.into_versioned_env(&engine.get_api_version()); + + versioned_env.set_contract_hash(&contract_hash); + + #[cfg(feature = "random")] + set_random_in_env(block_height, &contract_key, &mut engine, &mut versioned_env); + + update_msg_counter(block_height); + //let start = Instant::now(); + let result = engine.migrate(&versioned_env, validated_msg); + // let duration = start.elapsed(); + // trace!("Time elapsed in engine.init: {:?}", duration); + + *used_gas = engine.gas_used(); + + let output = result?; + + engine + .flush_cache() + .map_err(|_| EnclaveError::FailedFunctionCall)?; + + // TODO: copy cosmwasm's structures to enclave + // TODO: ref: https://github.com/CosmWasm/cosmwasm/blob/b971c037a773bf6a5f5d08a88485113d9b9e8e7b/packages/std/src/init_handle.rs#L129 + // TODO: ref: https://github.com/CosmWasm/cosmwasm/blob/b971c037a773bf6a5f5d08a88485113d9b9e8e7b/packages/std/src/query.rs#L13 + //let start = Instant::now(); + + let output = post_process_output( + output, + &secret_msg, + &canonical_contract_address, + versioned_env.get_contract_hash(), + reply_params, + &canonical_sender_address, + false, + false, + )?; + + // let duration = start.elapsed(); + // trace!("Time elapsed in encrypt_output: {:?}", duration); + + // todo: can move the key to somewhere in the output message if we want + + Ok(MigrateSuccess { output }) +} + #[cfg_attr(feature = "cargo-clippy", allow(clippy::too_many_arguments))] pub fn handle( context: Ctx, @@ -362,8 +513,7 @@ pub fn handle( manipulate_callback_sig_for_plaintext(&canonical_contract_address, output)?; set_all_logs_to_plaintext(&mut raw_output); - output = - finalize_raw_output(raw_output, false, is_ibc_msg(parsed_handle_type), false)?; + output = finalize_raw_output(raw_output, false, is_ibc_msg(parsed_handle_type), false)?; } Ok(HandleSuccess { output }) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/cosmwasm_config.rs b/cosmwasm/enclaves/shared/contract-engine/src/cosmwasm_config.rs index 67001adfc..45c0dc857 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/cosmwasm_config.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/cosmwasm_config.rs @@ -15,6 +15,7 @@ pub enum ContractOperation { Init, Handle, Query, + Migrate, } #[allow(unused)] @@ -30,6 +31,10 @@ impl ContractOperation { pub fn is_query(&self) -> bool { matches!(self, ContractOperation::Query) } + + pub fn is_migrate(&self) -> bool { + matches!(self, ContractOperation::Migrate) + } } //pub const MAX_LOG_LENGTH: usize = 8192; diff --git a/cosmwasm/enclaves/shared/contract-engine/src/external/ecalls.rs b/cosmwasm/enclaves/shared/contract-engine/src/external/ecalls.rs index ece79d786..202b49219 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/external/ecalls.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/external/ecalls.rs @@ -8,15 +8,15 @@ use log::*; use sgx_types::sgx_status_t; use enclave_ffi_types::{ - Ctx, EnclaveBuffer, EnclaveError, HandleResult, HealthCheckResult, InitResult, QueryResult, - RuntimeConfiguration, + Ctx, EnclaveBuffer, EnclaveError, HandleResult, HealthCheckResult, InitResult, MigrateResult, + QueryResult, RuntimeConfiguration, }; use enclave_utils::{oom_handler, validate_const_ptr, validate_mut_ptr}; use crate::external::results::{ result_handle_success_to_handleresult, result_init_success_to_initresult, - result_query_success_to_queryresult, + result_migrate_success_to_result, result_query_success_to_queryresult, }; lazy_static! { @@ -408,6 +408,88 @@ unsafe fn ecall_query_impl( } } +/// # Safety +/// Always use protection +#[no_mangle] +pub unsafe extern "C" fn ecall_migrate( + context: Ctx, + gas_limit: u64, + used_gas: *mut u64, + contract: *const u8, + contract_len: usize, + env: *const u8, + env_len: usize, + msg: *const u8, + msg_len: usize, + sig_info: *const u8, + sig_info_len: usize, + admin: *const u8, + admin_len: usize, + admin_proof: *const u8, + admin_proof_len: usize, +) -> MigrateResult { + if let Err(err) = oom_handler::register_oom_handler() { + error!("Could not register OOM handler!"); + return MigrateResult::Failure { err }; + } + + let failed_call = || result_migrate_success_to_result(Err(EnclaveError::FailedFunctionCall)); + validate_mut_ptr!(used_gas as _, std::mem::size_of::(), failed_call()); + validate_const_ptr!(env, env_len as usize, failed_call()); + validate_const_ptr!(msg, msg_len as usize, failed_call()); + validate_const_ptr!(contract, contract_len as usize, failed_call()); + validate_const_ptr!(sig_info, sig_info_len as usize, failed_call()); + validate_const_ptr!(admin, admin_len as usize, failed_call()); + validate_const_ptr!(admin_proof, admin_proof_len as usize, failed_call()); + + let contract = std::slice::from_raw_parts(contract, contract_len); + let env = std::slice::from_raw_parts(env, env_len); + let msg = std::slice::from_raw_parts(msg, msg_len); + let sig_info = std::slice::from_raw_parts(sig_info, sig_info_len); + let admin = std::slice::from_raw_parts(admin, admin_len); + let admin_proof = std::slice::from_raw_parts(admin_proof, admin_proof_len); + + let result = panic::catch_unwind(|| { + let mut local_used_gas = *used_gas; + let result = crate::contract_operations::migrate( + context, + gas_limit, + &mut local_used_gas, + contract, + env, + msg, + sig_info, + admin, + admin_proof, + ); + *used_gas = local_used_gas; + result_migrate_success_to_result(result) + }); + + if let Err(err) = oom_handler::restore_safety_buffer() { + error!("Could not restore OOM safety buffer!"); + return MigrateResult::Failure { err }; + } + + if let Ok(res) = result { + res + } else { + *used_gas = gas_limit / 2; + + if oom_handler::get_then_clear_oom_happened() { + error!("Call ecall_handle failed because the enclave ran out of memory!"); + MigrateResult::Failure { + err: EnclaveError::OutOfMemory, + } + } else { + error!("Call ecall_handle panicked unexpectedly!"); + MigrateResult::Failure { + err: EnclaveError::Panic, + } + } + } +} + /// # Safety /// Always use protection #[no_mangle] diff --git a/cosmwasm/enclaves/shared/contract-engine/src/external/results.rs b/cosmwasm/enclaves/shared/contract-engine/src/external/results.rs index 6aa20f238..1359f8453 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/external/results.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/external/results.rs @@ -1,7 +1,8 @@ use sgx_types::sgx_status_t; use enclave_ffi_types::{ - EnclaveError, HandleResult, InitResult, QueryResult, UntrustedVmError, UserSpaceBuffer, + EnclaveError, HandleResult, InitResult, MigrateResult, QueryResult, UntrustedVmError, + UserSpaceBuffer, }; use crate::external::ocalls::ocall_allocate; @@ -12,6 +13,7 @@ pub struct InitSuccess { pub output: Vec, /// The contract_key of this contract. pub contract_key: [u8; 64], + pub admin_proof: [u8; 32], } pub fn result_init_success_to_initresult(result: Result) -> InitResult { @@ -19,6 +21,7 @@ pub fn result_init_success_to_initresult(result: Result { let user_buffer = unsafe { let mut user_buffer = std::mem::MaybeUninit::::uninit(); @@ -37,6 +40,7 @@ pub fn result_init_success_to_initresult(result: Result InitResult::Failure { err }, @@ -76,6 +80,39 @@ pub fn result_handle_success_to_handleresult( } } +/// This struct is returned from a handle method. +pub struct MigrateSuccess { + /// The output of the calculation + pub output: Vec, +} + +pub fn result_migrate_success_to_result( + result: Result, +) -> MigrateResult { + match result { + Ok(MigrateSuccess { output }) => { + let user_buffer = unsafe { + let mut user_buffer = std::mem::MaybeUninit::::uninit(); + match ocall_allocate(user_buffer.as_mut_ptr(), output.as_ptr(), output.len()) { + sgx_status_t::SGX_SUCCESS => { /* continue */ } + _ => { + return MigrateResult::Failure { + err: EnclaveError::FailedOcall { + vm_error: UntrustedVmError::default(), + }, + } + } + } + user_buffer.assume_init() + }; + MigrateResult::Success { + output: user_buffer, + } + } + Err(err) => MigrateResult::Failure { err }, + } +} + /// This struct is returned from a query method. pub struct QuerySuccess { /// The output of the calculation diff --git a/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs b/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs index 8f2c3af28..1395993dc 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs @@ -377,6 +377,71 @@ impl Engine { &self.features } + pub fn migrate(&mut self, env: &CwEnv, msg: Vec) -> Result, EnclaveError> { + let api_version = self.get_api_version(); + + self.with_instance(|instance, context| { + debug!("starting migrate, api version: {:?}", api_version); + + let (env_bytes, msg_info_bytes) = env.get_wasm_ptrs()?; + + // let start = Instant::now(); + let env_ptr = write_to_memory(instance, &env_bytes)?; + // let duration = start.elapsed(); + // trace!( + // "Time elapsed in env_bytes write_to_memory is: {:?}", + // duration + // ); + + // let start = Instant::now(); + let msg_ptr = write_to_memory(instance, &msg)?; + // let duration = start.elapsed(); + // trace!("Time elapsed in msg write_to_memory is: {:?}", duration); + + let result = match api_version { + CosmWasmApiVersion::V010 => { + let (init, args) = ( + instance + .find_function::<(u32, u32), u32>("migrate") + .to_enclave_result()?, + (env_ptr, msg_ptr), + ); + init.call_with_context(context, args) + } + CosmWasmApiVersion::V1 => { + let msg_info_ptr = write_to_memory(instance, &msg_info_bytes)?; + + let (init, args) = ( + instance + .find_function::<(u32, u32, u32), u32>("migrate") + .to_enclave_result()?, + (env_ptr, msg_info_ptr, msg_ptr), + ); + // let start = Instant::now(); + // let res = + init.call_with_context(context, args) + // let duration = start.elapsed(); + // trace!("Time elapsed in call_with_context is: {:?}", duration); + // res + } + CosmWasmApiVersion::Invalid => { + return Err(EnclaveError::InvalidWasm); + } + }; + // let start = Instant::now(); + let output_ptr = check_execution_result(instance, context, result)?; + // let duration = start.elapsed(); + // trace!("Time elapsed in check_execution_result is: {:?}", duration); + + // let start = Instant::now(); + let output = read_from_memory(instance, output_ptr)?; + // let duration = start.elapsed(); + // trace!("Time elapsed in read_from_memory is: {:?}", duration); + + Ok(output) + }) + } + pub fn init(&mut self, env: &CwEnv, msg: Vec) -> Result, EnclaveError> { let api_version = self.get_api_version(); @@ -849,6 +914,7 @@ fn host_read_db( ContractOperation::Init => true, ContractOperation::Handle => true, ContractOperation::Query => false, + ContractOperation::Migrate => true, }, &mut context.kv_cache, &get_encryption_salt(context.timestamp), diff --git a/cosmwasm/packages/sgx-vm/src/calls.rs b/cosmwasm/packages/sgx-vm/src/calls.rs index 2e6689887..60d0c69cb 100644 --- a/cosmwasm/packages/sgx-vm/src/calls.rs +++ b/cosmwasm/packages/sgx-vm/src/calls.rs @@ -72,6 +72,23 @@ pub fn call_query( } */ +/// Calls Wasm export "init" and returns raw data from the contract. +/// The result is length limited to prevent abuse but otherwise unchecked. +pub fn call_migrate_raw( + instance: &mut Instance, + env: &[u8], + msg: &[u8], + sig_info: &[u8], + admin: &[u8], + admin_proof: &[u8], +) -> VmResult> { + instance.set_storage_readonly(false); + /* + call_raw(instance, "init", &[env, msg], MAX_LENGTH_INIT) + */ + instance.call_migrate(env, msg, sig_info, admin, admin_proof) +} + /// Calls Wasm export "init" and returns raw data from the contract. /// The result is length limited to prevent abuse but otherwise unchecked. pub fn call_init_raw( diff --git a/cosmwasm/packages/sgx-vm/src/instance.rs b/cosmwasm/packages/sgx-vm/src/instance.rs index 3f0644533..e05e82776 100644 --- a/cosmwasm/packages/sgx-vm/src/instance.rs +++ b/cosmwasm/packages/sgx-vm/src/instance.rs @@ -326,6 +326,18 @@ where Ok(function) } + pub fn call_migrate( + &mut self, + env: &[u8], + msg: &[u8], + sig_info: &[u8], + admin: &[u8], + admin_proof: &[u8], + ) -> VmResult> { + let result = self.inner.migrate(env, msg, sig_info, admin, admin_proof)?; + Ok(result.into_output()) + } + pub fn call_init( &mut self, env: &[u8], diff --git a/cosmwasm/packages/sgx-vm/src/lib.rs b/cosmwasm/packages/sgx-vm/src/lib.rs index f84da3ea1..a43e0371f 100644 --- a/cosmwasm/packages/sgx-vm/src/lib.rs +++ b/cosmwasm/packages/sgx-vm/src/lib.rs @@ -30,7 +30,7 @@ mod random; pub mod enclave_tests; pub use crate::cache::CosmCache; -pub use crate::calls::{call_handle_raw, call_init_raw, call_query_raw}; +pub use crate::calls::{call_handle_raw, call_init_raw, call_migrate_raw, call_query_raw}; pub use crate::checksum::Checksum; pub use crate::errors::{ CommunicationError, CommunicationResult, RegionValidationError, RegionValidationResult, diff --git a/cosmwasm/packages/sgx-vm/src/wasmi/imports.rs b/cosmwasm/packages/sgx-vm/src/wasmi/imports.rs index 031f7a85e..a516b3854 100644 --- a/cosmwasm/packages/sgx-vm/src/wasmi/imports.rs +++ b/cosmwasm/packages/sgx-vm/src/wasmi/imports.rs @@ -4,7 +4,7 @@ use log::*; use sgx_types::{sgx_enclave_id_t, sgx_status_t, SgxResult}; -use enclave_ffi_types::{Ctx, EnclaveBuffer, HandleResult, InitResult, QueryResult}; +use enclave_ffi_types::{Ctx, EnclaveBuffer, HandleResult, InitResult, MigrateResult, QueryResult}; use crate::enclave::ENCLAVE_DOORBELL; @@ -17,6 +17,26 @@ extern "C" { length: usize, ) -> sgx_status_t; + pub fn ecall_migrate( + eid: sgx_enclave_id_t, + retval: *mut MigrateResult, + context: Ctx, + gas_limit: u64, + used_gas: *mut u64, + contract: *const u8, + contract_len: usize, + env: *const u8, + env_len: usize, + msg: *const u8, + msg_len: usize, + sig_info: *const u8, + sig_info_len: usize, + admin: *const u8, + admin_len: usize, + admin_proof: *const u8, + admin_proof_len: usize, + ) -> sgx_status_t; + /// Trigger the init method in a wasm contract pub fn ecall_init( eid: sgx_enclave_id_t, diff --git a/cosmwasm/packages/sgx-vm/src/wasmi/results.rs b/cosmwasm/packages/sgx-vm/src/wasmi/results.rs index 64f71cf97..1cde197a8 100644 --- a/cosmwasm/packages/sgx-vm/src/wasmi/results.rs +++ b/cosmwasm/packages/sgx-vm/src/wasmi/results.rs @@ -1,6 +1,6 @@ use super::exports; use crate::VmResult; -use enclave_ffi_types::{HandleResult, InitResult, QueryResult}; +use enclave_ffi_types::{HandleResult, InitResult, MigrateResult, QueryResult}; /// This struct is returned from module initialization. pub struct InitSuccess { @@ -8,11 +8,13 @@ pub struct InitSuccess { output: Vec, /// The contract_key for this contract. contract_key: [u8; 64], + admin_proof: [u8; 32], } impl InitSuccess { pub fn into_output(self) -> Vec { let mut out_vec = self.contract_key.to_vec(); + out_vec.extend_from_slice(&self.admin_proof); out_vec.extend_from_slice(&self.output); out_vec } @@ -23,14 +25,37 @@ pub fn init_result_to_vm_result(other: InitResult) -> VmResult { InitResult::Success { output, contract_key, + admin_proof, } => Ok(InitSuccess { output: unsafe { exports::recover_buffer(output) }.unwrap_or_else(Vec::new), contract_key, + admin_proof, }), InitResult::Failure { err } => Err(err.into()), } } +pub fn migrate_result_to_vm_result(other: MigrateResult) -> VmResult { + match other { + MigrateResult::Success { output } => Ok(MigrateSuccess { + output: unsafe { exports::recover_buffer(output) }.unwrap_or_else(Vec::new), + }), + MigrateResult::Failure { err } => Err(err.into()), + } +} + +/// This struct is returned from a handle method. +pub struct MigrateSuccess { + /// A pointer to the output of the execution + output: Vec, +} + +impl MigrateSuccess { + pub fn into_output(self) -> Vec { + self.output + } +} + /// This struct is returned from a handle method. pub struct HandleSuccess { /// A pointer to the output of the execution diff --git a/cosmwasm/packages/sgx-vm/src/wasmi/wrapper.rs b/cosmwasm/packages/sgx-vm/src/wasmi/wrapper.rs index 8060acd65..7e19f982d 100644 --- a/cosmwasm/packages/sgx-vm/src/wasmi/wrapper.rs +++ b/cosmwasm/packages/sgx-vm/src/wasmi/wrapper.rs @@ -10,10 +10,11 @@ use crate::enclave::ENCLAVE_DOORBELL; use crate::errors::{EnclaveError, VmResult}; use crate::{Querier, Storage, VmError}; -use enclave_ffi_types::{Ctx, HandleResult, InitResult, QueryResult}; +use enclave_ffi_types::{Ctx, HandleResult, InitResult, MigrateResult, QueryResult}; use sgx_types::sgx_status_t; +use crate::wasmi::results::{migrate_result_to_vm_result, MigrateSuccess}; use log::*; use serde::Deserialize; @@ -92,6 +93,69 @@ where VmError::generic_err("The enclave is too busy and can not respond to this query") } + pub fn migrate( + &mut self, + env: &[u8], + msg: &[u8], + sig_info: &[u8], + admin: &[u8], + admin_proof: &[u8], + ) -> VmResult { + trace!( + "init() called with env: {:?} msg: {:?} gas_left: {}", + String::from_utf8_lossy(env), + String::from_utf8_lossy(msg), + self.gas_left() + ); + + let mut migrate_result = MaybeUninit::::uninit(); + let mut used_gas = 0_u64; + + // Bind the token to a local variable to ensure its + // destructor runs in the end of the function + let enclave_access_token = ENCLAVE_DOORBELL + .get_access(1) // This can never be recursive + .ok_or_else(Self::busy_enclave_err)?; + let enclave = enclave_access_token.map_err(EnclaveError::sdk_err)?; + + let status = unsafe { + imports::ecall_migrate( + enclave.geteid(), + migrate_result.as_mut_ptr(), + self.ctx.unsafe_clone(), + self.gas_left(), + &mut used_gas, + self.bytecode.as_ptr(), + self.bytecode.len(), + env.as_ptr(), + env.len(), + msg.as_ptr(), + msg.len(), + sig_info.as_ptr(), + sig_info.len(), + admin.as_ptr(), + admin.len(), + admin_proof.as_ptr(), + admin_proof.len(), + ) + }; + + trace!( + "migrate() returned with gas_used: {} (gas_limit: {})", + used_gas, + self.gas_limit + ); + self.consume_gas(used_gas); + + match status { + sgx_status_t::SGX_SUCCESS => { + let migrate_result = unsafe { migrate_result.assume_init() }; + migrate_result_to_vm_result(migrate_result) + } + failure_status => Err(EnclaveError::sdk_err(failure_status).into()), + } + } + pub fn init( &mut self, env: &[u8], diff --git a/go-cosmwasm/api/lib.go b/go-cosmwasm/api/lib.go index 2e124a133..9b0a7cd20 100644 --- a/go-cosmwasm/api/lib.go +++ b/go-cosmwasm/api/lib.go @@ -149,6 +149,60 @@ func GetCode(cache Cache, code_id []byte) ([]byte, error) { return receiveVector(code), nil } +func Migrate( + cache Cache, + code_id []byte, + params []byte, + msg []byte, + gasMeter *GasMeter, + store KVStore, + api *GoAPI, + querier *Querier, + gasLimit uint64, + sigInfo []byte, + admin []byte, + adminProof []byte, +) ([]byte, uint64, error) { + id := sendSlice(code_id) + defer freeAfterSend(id) + p := sendSlice(params) + defer freeAfterSend(p) + m := sendSlice(msg) + defer freeAfterSend(m) + + // set up a new stack frame to handle iterators + counter := startContract() + defer endContract(counter) + + dbState := buildDBState(store, counter) + db := buildDB(&dbState, gasMeter) + + s := sendSlice(sigInfo) + defer freeAfterSend(s) + a := buildAPI(api) + q := buildQuerier(querier) + var gasUsed u64 + errmsg := C.Buffer{} + + adminBuffer := sendSlice(admin) + defer freeAfterSend(adminBuffer) + + adminProofBuffer := sendSlice(adminProof) + defer freeAfterSend(adminBuffer) + + //// This is done in order to ensure that goroutines don't + //// swap threads between recursive calls to the enclave. + //runtime.LockOSThread() + //defer runtime.UnlockOSThread() + + res, err := C.migrate(cache.ptr, id, p, m, db, a, q, u64(gasLimit), &gasUsed, &errmsg, s, adminBuffer, adminProofBuffer) + if err != nil && err.(syscall.Errno) != C.ErrnoValue_Success { + // Depending on the nature of the error, `gasUsed` will either have a meaningful value, or just 0. + return nil, uint64(gasUsed), errorWithMessage(err, errmsg) + } + return receiveVector(res), uint64(gasUsed), nil +} + func Instantiate( cache Cache, code_id []byte, diff --git a/go-cosmwasm/lib.go b/go-cosmwasm/lib.go index 338c4772d..d4f83ca50 100644 --- a/go-cosmwasm/lib.go +++ b/go-cosmwasm/lib.go @@ -141,31 +141,33 @@ func (w *Wasmer) Instantiate( gasLimit uint64, sigInfo types.VerificationInfo, admin sdk.AccAddress, -) (interface{}, []byte, uint64, error) { + // data, contractKey, adminProof, gasUsed, error +) (interface{}, []byte, []byte, uint64, error) { paramBin, err := json.Marshal(env) if err != nil { - return nil, nil, 0, err + return nil, nil, nil, 0, err } sigInfoBin, err := json.Marshal(sigInfo) if err != nil { - return nil, nil, 0, err + return nil, nil, nil, 0, err } data, gasUsed, err := api.Instantiate(w.cache, codeId, paramBin, initMsg, &gasMeter, store, &goapi, &querier, gasLimit, sigInfoBin, admin) if err != nil { - return nil, nil, gasUsed, err + return nil, nil, nil, gasUsed, err } key := data[0:64] - data = data[64:] + adminProof := data[64:96] + data = data[96:] var respV010orV1 V010orV1ContractInitResponse err = json.Unmarshal(data, &respV010orV1) if err != nil { // unidentified response 🤷 - return nil, nil, gasUsed, fmt.Errorf("instantiate: cannot parse response from json: %w", err) + return nil, nil, nil, gasUsed, fmt.Errorf("instantiate: cannot parse response from json: %w", err) } isOutputAddressedToReply := len(respV010orV1.InternaReplyEnclaveSig) > 0 && len(respV010orV1.InternalMsgId) > 0 @@ -177,18 +179,18 @@ func (w *Wasmer) Instantiate( InternalMsgId: respV010orV1.InternalMsgId, InternaReplyEnclaveSig: respV010orV1.InternaReplyEnclaveSig, Data: []byte(respV010orV1.V010.Err.GenericErr.Msg), - }, nil, gasUsed, fmt.Errorf("%+v", respV010orV1.V010.Err) + }, nil, nil, gasUsed, fmt.Errorf("%+v", respV010orV1.V010.Err) } if respV010orV1.V010.Ok != nil { if isOutputAddressedToReply { respV010orV1.V010.Ok.Data, err = AppendReplyInternalDataToData(respV010orV1.V010.Ok.Data, respV010orV1.InternaReplyEnclaveSig, respV010orV1.InternalMsgId) if err != nil { - return nil, nil, gasUsed, fmt.Errorf("cannot serialize v0.10 DataWithInternalReplyInfo into binary : %w", err) + return nil, nil, nil, gasUsed, fmt.Errorf("cannot serialize v0.10 DataWithInternalReplyInfo into binary : %w", err) } } - return respV010orV1.V010.Ok, key, gasUsed, nil + return respV010orV1.V010.Ok, key, adminProof, gasUsed, nil } } @@ -199,22 +201,22 @@ func (w *Wasmer) Instantiate( InternalMsgId: respV010orV1.InternalMsgId, InternaReplyEnclaveSig: respV010orV1.InternaReplyEnclaveSig, Data: []byte(respV010orV1.V1.Err.GenericErr.Msg), - }, nil, gasUsed, fmt.Errorf("%+v", respV010orV1.V1.Err) + }, nil, nil, gasUsed, fmt.Errorf("%+v", respV010orV1.V1.Err) } if respV010orV1.V1.Ok != nil { if isOutputAddressedToReply { respV010orV1.V1.Ok.Data, err = AppendReplyInternalDataToData(respV010orV1.V1.Ok.Data, respV010orV1.InternaReplyEnclaveSig, respV010orV1.InternalMsgId) if err != nil { - return nil, nil, gasUsed, fmt.Errorf("cannot serialize v1 DataWithInternalReplyInfo into binary: %w", err) + return nil, nil, nil, gasUsed, fmt.Errorf("cannot serialize v1 DataWithInternalReplyInfo into binary: %w", err) } } - return respV010orV1.V1.Ok, key, gasUsed, nil + return respV010orV1.V1.Ok, key, adminProof, gasUsed, nil } } - return nil, nil, gasUsed, fmt.Errorf("instantiate: cannot detect response type (v0.10 or v1)") + return nil, nil, nil, gasUsed, fmt.Errorf("instantiate: cannot detect response type (v0.10 or v1)") } func AppendReplyInternalDataToData(data []byte, internaReplyEnclaveSig []byte, internalMsgId []byte) ([]byte, error) { @@ -404,7 +406,7 @@ func (w *Wasmer) AnalyzeCode( // // MigrateMsg has some data on how to perform the migration. func (w *Wasmer) Migrate( - newCodeId CodeID, + newCodeId CodeHash, env types.Env, migrateMsg []byte, store KVStore, @@ -413,103 +415,78 @@ func (w *Wasmer) Migrate( gasMeter GasMeter, gasLimit uint64, sigInfo types.VerificationInfo, + admin sdk.AccAddress, + adminProof []byte, + // data, contractKey, adminProof, gasUsed, error ) (interface{}, uint64, error) { paramBin, err := json.Marshal(env) if err != nil { return nil, 0, err } + sigInfoBin, err := json.Marshal(sigInfo) if err != nil { return nil, 0, err } - data, gasUsed, err := api.Handle(w.cache, newCodeId, paramBin, migrateMsg, &gasMeter, store, &goapi, &querier, gasLimit, sigInfoBin, types.HandleTypeMigrate) + data, gasUsed, err := api.Migrate(w.cache, newCodeId, paramBin, migrateMsg, &gasMeter, store, &goapi, &querier, gasLimit, sigInfoBin, admin, adminProof) if err != nil { return nil, gasUsed, err } - var resp ContractExecResponse - err = json.Unmarshal(data, &resp) + var respV010orV1 V010orV1ContractInitResponse + err = json.Unmarshal(data, &respV010orV1) if err != nil { // unidentified response 🤷 - return nil, gasUsed, fmt.Errorf("handle: cannot parse response from json: %w", err) + return nil, gasUsed, fmt.Errorf("migrate: cannot parse response from json: %w", err) } - isOutputAddressedToReply := (len(resp.InternaReplyEnclaveSig) > 0 && len(resp.InternalMsgId) > 0) + isOutputAddressedToReply := len(respV010orV1.InternaReplyEnclaveSig) > 0 && len(respV010orV1.InternalMsgId) > 0 - // handle v0.10 response - if resp.V010 != nil { - if resp.V010.Err != nil { //nolint:gocritic + // init v0.10 response + if respV010orV1.V010 != nil { + if respV010orV1.V010.Err != nil { return v1types.DataWithInternalReplyInfo{ - InternalMsgId: resp.InternalMsgId, - InternaReplyEnclaveSig: resp.InternaReplyEnclaveSig, - Data: []byte(resp.V010.Err.GenericErr.Msg), - }, gasUsed, fmt.Errorf("%+v", resp.V010.Err) - } else if resp.V010.Ok != nil { + InternalMsgId: respV010orV1.InternalMsgId, + InternaReplyEnclaveSig: respV010orV1.InternaReplyEnclaveSig, + Data: []byte(respV010orV1.V010.Err.GenericErr.Msg), + }, gasUsed, fmt.Errorf("%+v", respV010orV1.V010.Err) + } + + if respV010orV1.V010.Ok != nil { if isOutputAddressedToReply { - resp.V010.Ok.Data, err = AppendReplyInternalDataToData(resp.V010.Ok.Data, resp.InternaReplyEnclaveSig, resp.InternalMsgId) + respV010orV1.V010.Ok.Data, err = AppendReplyInternalDataToData(respV010orV1.V010.Ok.Data, respV010orV1.InternaReplyEnclaveSig, respV010orV1.InternalMsgId) if err != nil { return nil, gasUsed, fmt.Errorf("cannot serialize v0.10 DataWithInternalReplyInfo into binary : %w", err) } } - return resp.V010.Ok, gasUsed, nil - } else { - return nil, gasUsed, fmt.Errorf("cannot parse v0.10 handle response: %+v", resp) + + return respV010orV1.V010.Ok, gasUsed, nil } } - // handle v1 response - if resp.V1 != nil { - if resp.V1.Err != nil { //nolint:gocritic + // init v1 response + if respV010orV1.V1 != nil { + if respV010orV1.V1.Err != nil { return v1types.DataWithInternalReplyInfo{ - InternalMsgId: resp.InternalMsgId, - InternaReplyEnclaveSig: resp.InternaReplyEnclaveSig, - Data: []byte(resp.V1.Err.GenericErr.Msg), - }, gasUsed, fmt.Errorf("%+v", resp.V1.Err) - } else if resp.V1.Ok != nil { + InternalMsgId: respV010orV1.InternalMsgId, + InternaReplyEnclaveSig: respV010orV1.InternaReplyEnclaveSig, + Data: []byte(respV010orV1.V1.Err.GenericErr.Msg), + }, gasUsed, fmt.Errorf("%+v", respV010orV1.V1.Err) + } + + if respV010orV1.V1.Ok != nil { if isOutputAddressedToReply { - resp.V1.Ok.Data, err = AppendReplyInternalDataToData(resp.V1.Ok.Data, resp.InternaReplyEnclaveSig, resp.InternalMsgId) + respV010orV1.V1.Ok.Data, err = AppendReplyInternalDataToData(respV010orV1.V1.Ok.Data, respV010orV1.InternaReplyEnclaveSig, respV010orV1.InternalMsgId) if err != nil { return nil, gasUsed, fmt.Errorf("cannot serialize v1 DataWithInternalReplyInfo into binary: %w", err) } } - return resp.V1.Ok, gasUsed, nil - } else { - return nil, gasUsed, fmt.Errorf("cannot parse v1 handle response: %+v", resp) - } - } - - if resp.IBCBasic != nil { - if resp.IBCBasic.Err != nil { //nolint:gocritic - return nil, gasUsed, fmt.Errorf("%+v", resp.IBCBasic.Err) - } else if resp.IBCBasic.Ok != nil { - return resp.IBCBasic.Ok, gasUsed, nil - } else { - return nil, gasUsed, fmt.Errorf("cannot parse IBCBasic response: %+v", resp) - } - } - if resp.IBCPacketReceive != nil { - if resp.IBCPacketReceive.Err != nil { //nolint:gocritic - return nil, gasUsed, fmt.Errorf("%+v", resp.IBCPacketReceive.Err) - } else if resp.IBCPacketReceive.Ok != nil { - return resp.IBCPacketReceive.Ok, gasUsed, nil - } else { - return nil, gasUsed, fmt.Errorf("cannot parse IBCPacketReceive response: %+v", resp) + return respV010orV1.V1.Ok, gasUsed, nil } } - if resp.IBCChannelOpen != nil { - if resp.IBCChannelOpen.Err != nil { //nolint:gocritic - return nil, gasUsed, fmt.Errorf("%+v", resp.IBCChannelOpen.Err) - } else if resp.IBCChannelOpen.Ok != nil { - // ibc_channel_open actually returns no data - return resp.IBCChannelOpen.Ok, gasUsed, nil - } else { - return nil, gasUsed, fmt.Errorf("cannot parse IBCChannelOpen response: %+v", resp) - } - } - - return nil, gasUsed, fmt.Errorf("handle: cannot detect response type (v0.10 or v1)") + return nil, gasUsed, fmt.Errorf("instantiate: cannot detect response type (v0.10 or v1)") } diff --git a/go-cosmwasm/src/lib.rs b/go-cosmwasm/src/lib.rs index 8d3265623..fb2cb4d35 100644 --- a/go-cosmwasm/src/lib.rs +++ b/go-cosmwasm/src/lib.rs @@ -21,7 +21,8 @@ use crate::error::{clear_error, handle_c_error, handle_c_error_default, set_erro use cosmwasm_sgx_vm::untrusted_init_bootstrap; use cosmwasm_sgx_vm::{ - call_handle_raw, call_init_raw, call_query_raw, features_from_csv, Checksum, CosmCache, Extern, + call_handle_raw, call_init_raw, call_migrate_raw, call_query_raw, features_from_csv, Checksum, + CosmCache, Extern, }; use cosmwasm_sgx_vm::{ create_attestation_report_u, untrusted_get_encrypted_genesis_seed, @@ -334,6 +335,7 @@ static PARAMS_ARG: &str = "params"; static GAS_USED_ARG: &str = "gas_used"; static SIG_INFO_ARG: &str = "sig_info"; static ADMIN_ARG: &str = "admin"; +static ADMIN_PROOF_ARG: &str = "admin_proof"; fn do_init_cache( data_dir: Buffer, @@ -499,6 +501,81 @@ fn do_init( Ok(res?) } +#[no_mangle] +pub extern "C" fn migrate( + cache: *mut cache_t, + contract_id: Buffer, + params: Buffer, + msg: Buffer, + db: DB, + api: GoApi, + querier: GoQuerier, + gas_limit: u64, + gas_used: Option<&mut u64>, + err: Option<&mut Buffer>, + sig_info: Buffer, + admin: Buffer, + admin_proof: Buffer, +) -> Buffer { + let r = match to_cache(cache) { + Some(c) => catch_unwind(AssertUnwindSafe(move || { + do_migrate( + c, + contract_id, + params, + msg, + db, + api, + querier, + gas_limit, + gas_used, + sig_info, + admin, + admin_proof, + ) + })) + .unwrap_or_else(|_| Err(Error::panic())), + None => Err(Error::empty_arg(CACHE_ARG)), + }; + let data = handle_c_error(r, err); + Buffer::from_vec(data) +} + +#[allow(clippy::too_many_arguments)] +fn do_migrate( + cache: &mut CosmCache, + code_id: Buffer, + params: Buffer, + msg: Buffer, + db: DB, + api: GoApi, + querier: GoQuerier, + gas_limit: u64, + gas_used: Option<&mut u64>, + sig_info: Buffer, + admin: Buffer, + admin_proof: Buffer, +) -> Result, Error> { + let gas_used = gas_used.ok_or_else(|| Error::empty_arg(GAS_USED_ARG))?; + let code_id: Checksum = unsafe { code_id.read() } + .ok_or_else(|| Error::empty_arg(CODE_ID_ARG))? + .try_into()?; + let params = unsafe { params.read() }.ok_or_else(|| Error::empty_arg(PARAMS_ARG))?; + let msg = unsafe { msg.read() }.ok_or_else(|| Error::empty_arg(MSG_ARG))?; + let sig_info = unsafe { sig_info.read() }.ok_or_else(|| Error::empty_arg(SIG_INFO_ARG))?; + let admin = unsafe { admin.read() }.ok_or_else(|| Error::empty_arg(ADMIN_ARG))?; + let admin_proof = + unsafe { admin_proof.read() }.ok_or_else(|| Error::empty_arg(ADMIN_PROOF_ARG))?; + + let deps = to_extern(db, api, querier); + let mut instance = cache.get_instance(&code_id, deps, gas_limit)?; + // We only check this result after reporting gas usage and returning the instance into the cache. + let res = call_migrate_raw(&mut instance, params, msg, sig_info, admin, admin_proof); + *gas_used = instance.create_gas_report().used_internally; + instance.recycle(); + Ok(res?) +} + #[no_mangle] pub extern "C" fn handle( cache: *mut cache_t, diff --git a/go-cosmwasm/types/types.go b/go-cosmwasm/types/types.go index b50d041ef..83d166bb4 100644 --- a/go-cosmwasm/types/types.go +++ b/go-cosmwasm/types/types.go @@ -78,7 +78,6 @@ const ( HandleTypeIbcPacketReceive HandleTypeIbcPacketAck HandleTypeIbcPacketTimeout - HandleTypeMigrate ) type CosmosMsgVersion int diff --git a/proto/secret/compute/v1beta1/types.proto b/proto/secret/compute/v1beta1/types.proto index 84d690f61..0ec11d516 100644 --- a/proto/secret/compute/v1beta1/types.proto +++ b/proto/secret/compute/v1beta1/types.proto @@ -46,7 +46,9 @@ message ContractInfo { AbsoluteTxPosition created = 5; string ibc_port_id = 6 [ (gogoproto.customname) = "IBCPortID" ]; // Admin is an optional address that can execute migrations - bytes admin = 7 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"]; + string admin = 7; + // Proof that enclave executed the instantiate command + bytes admin_proof = 8; } // AbsoluteTxPosition can be used to sort contracts diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index 2270befca..a1f14d781 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -419,7 +419,7 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator sdk.AccAddre // instantiate wasm contract gas := gasForContract(ctx) - response, key, gasUsed, err := k.wasmer.Instantiate(codeInfo.CodeHash, env, initMsg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, verificationInfo, admin) + response, key, adminProof, gasUsed, err := k.wasmer.Instantiate(codeInfo.CodeHash, env, initMsg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, verificationInfo, admin) consumeGas(ctx, gasUsed) if err != nil { @@ -442,7 +442,7 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator sdk.AccAddre // persist instance createdAt := types.NewAbsoluteTxPosition(ctx) - contractInfo := types.NewContractInfo(codeID, creator, admin, label, createdAt) + contractInfo := types.NewContractInfo(codeID, creator, admin, adminProof, label, createdAt) k.storeContractInfo(ctx, contractAddress, &contractInfo) store.Set(types.GetContractEnclaveKey(contractAddress), key) @@ -462,7 +462,7 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator sdk.AccAddre case *v1wasmTypes.Response: // persist instance first createdAt := types.NewAbsoluteTxPosition(ctx) - contractInfo := types.NewContractInfo(codeID, creator, admin, label, createdAt) + contractInfo := types.NewContractInfo(codeID, creator, admin, adminProof, label, createdAt) // check for IBC flag report, err := k.wasmer.AnalyzeCode(codeInfo.CodeHash) @@ -873,10 +873,10 @@ func (k *Keeper) handleContractResponse( logs []v010wasmTypes.LogAttribute, evts v1wasmTypes.Events, data []byte, - // original TX in order to extract the first 64bytes of signing info +// original TX in order to extract the first 64bytes of signing info ogTx []byte, - // sigInfo of the initial message that triggered the original contract call - // This is used mainly in replies in order to decrypt their data. +// sigInfo of the initial message that triggered the original contract call +// This is used mainly in replies in order to decrypt their data. ogSigInfo wasmTypes.VerificationInfo, ogCosmosMessageVersion wasmTypes.CosmosMsgVersion, ) ([]byte, error) { @@ -1154,8 +1154,12 @@ func (k Keeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller store := ctx.KVStore(k.storeKey) contractKey := store.Get(types.GetContractEnclaveKey(contractAddress)) + random := k.GetRandomSeed(ctx, ctx.BlockHeight()) + + env := types.NewEnv(ctx, caller, sdk.Coins{}, contractAddress, contractKey, random) - env := types.NewEnv(ctx, caller, sdk.Coins{}, contractAddress, contractKey) + adminProof := k.GetContractInfo(ctx, contractAddress).Admin //Proof + admin := k.GetContractInfo(ctx, contractAddress).Admin // prepare querier querier := QueryHandler{ @@ -1167,7 +1171,7 @@ func (k Keeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller // instantiate wasm contract gas := gasForContract(ctx) - response, gasUsed, err := k.wasmer.Execute(newCodeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, gasMeter(ctx), gas, verificationInfo, wasmTypes.HandleTypeMigrate) + response, gasUsed, err := k.wasmer.Migrate(newCodeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, gasMeter(ctx), gas, verificationInfo, admin, adminProof) consumeGas(ctx, gasUsed) if err != nil { diff --git a/x/compute/internal/types/types.go b/x/compute/internal/types/types.go index c8f52ff4d..3598936be 100644 --- a/x/compute/internal/types/types.go +++ b/x/compute/internal/types/types.go @@ -60,7 +60,7 @@ func NewCodeInfo(codeHash []byte, creator sdk.AccAddress, source string, builder } // NewContractInfo creates a new instance of a given WASM contract info -func NewContractInfo(codeID uint64, creator sdk.AccAddress, admin sdk.AccAddress, label string, createdAt *AbsoluteTxPosition) ContractInfo { +func NewContractInfo(codeID uint64, creator sdk.AccAddress, admin sdk.AccAddress, adminProof []byte, label string, createdAt *AbsoluteTxPosition) ContractInfo { return ContractInfo{ CodeID: codeID, Creator: creator, From efe52698fe464fd7508b828c348702aec8f32817 Mon Sep 17 00:00:00 2001 From: Itzik Grossman Date: Mon, 22 May 2023 23:40:32 +0300 Subject: [PATCH 008/164] Changed contract key to new format Fixed proto files Added validation for new contract key & proof --- cosmwasm/enclaves/ffi-types/src/types.rs | 2 + .../src/contract_operations.rs | 38 +- .../contract-engine/src/external/results.rs | 10 +- .../shared/cosmwasm-types/generic/src/lib.rs | 20 +- .../shared/cosmwasm-types/v0.10/src/types.rs | 24 +- cosmwasm/packages/sgx-vm/src/wasmi/results.rs | 15 +- go-cosmwasm/api/bindings.h | 14 + go-cosmwasm/api/lib_mock.go | 17 + go-cosmwasm/lib.go | 28 +- go-cosmwasm/types/env.go | 14 +- proto/secret/compute/v1beta1/query.proto | 3 + proto/secret/compute/v1beta1/types.proto | 12 +- x/compute/internal/keeper/keeper.go | 79 ++- x/compute/internal/keeper/legacy_querier.go | 6 +- x/compute/internal/keeper/querier.go | 5 + x/compute/internal/keeper/relay.go | 10 +- x/compute/internal/types/query.pb.go | 219 +++--- x/compute/internal/types/types.go | 17 +- x/compute/internal/types/types.pb.go | 670 ++++++++++++++++-- 19 files changed, 939 insertions(+), 264 deletions(-) diff --git a/cosmwasm/enclaves/ffi-types/src/types.rs b/cosmwasm/enclaves/ffi-types/src/types.rs index 509851e9b..33e653bd0 100644 --- a/cosmwasm/enclaves/ffi-types/src/types.rs +++ b/cosmwasm/enclaves/ffi-types/src/types.rs @@ -329,6 +329,8 @@ pub enum MigrateResult { Success { /// A pointer to the output of the calculation output: UserSpaceBuffer, + new_contract_key: [u8; 64], + proof: [u8; 32], }, Failure { /// The error that happened in the enclave diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 728dff4c6..22461da95 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -62,6 +62,20 @@ fn generate_admin_signature(admin: &[u8], code_hash: &[u8]) -> [u8; enclave_cryp sha_256(&data_to_hash) } +fn generate_contract_key_proof( + address: &[u8], + code_hash: &[u8], + prev_contract_key: &[u8], + new_contract_key: &[u8], +) -> [u8; enclave_crypto::HASH_SIZE] { + let mut data_to_hash = vec![]; + data_to_hash.extend_from_slice(address); + data_to_hash.extend_from_slice(code_hash); + data_to_hash.extend_from_slice(prev_contract_key); + data_to_hash.extend_from_slice(new_contract_key); + sha_256(&data_to_hash) +} + pub fn init( context: Ctx, // need to pass this to read_db & write_db gas_limit: u64, // gas limit for this execution @@ -282,6 +296,15 @@ pub fn migrate( &canonical_contract_address, )?; + let og_contract_key = base_env.get_contract_key()?; + + let contract_key_proof = generate_contract_key_proof( + &canonical_sender_address.0 .0, + &contract_code.hash(), + &og_contract_key, + &contract_key, + ); + let parsed_sig_info: SigInfo = extract_sig_info(sig_info)?; let secret_msg = SecretMessage::from_slice(msg)?; @@ -368,7 +391,11 @@ pub fn migrate( // todo: can move the key to somewhere in the output message if we want - Ok(MigrateSuccess { output }) + Ok(MigrateSuccess { + output, + new_contract_key: contract_key, + proof: contract_key_proof, + }) } #[cfg_attr(feature = "cargo-clippy", allow(clippy::too_many_arguments))] @@ -400,10 +427,17 @@ pub fn handle( let canonical_contract_address = to_canonical(contract_address)?; - let contract_key = base_env.get_contract_key()?; + let mut contract_key = base_env.get_contract_key()?; validate_contract_key(&contract_key, &canonical_contract_address, &contract_code)?; + if base_env.was_migrated() { + let og_key = base_env.get_original_contract_key().unwrap(); // was_migrated checks that this won't fail + contract_key = og_key.get_key(); + + // validate proof + } + let parsed_sig_info: SigInfo = extract_sig_info(sig_info)?; // The flow of handle is now used for multiple messages (such ash Handle, Reply) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/external/results.rs b/cosmwasm/enclaves/shared/contract-engine/src/external/results.rs index 1359f8453..bce0e5b4f 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/external/results.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/external/results.rs @@ -84,13 +84,19 @@ pub fn result_handle_success_to_handleresult( pub struct MigrateSuccess { /// The output of the calculation pub output: Vec, + pub new_contract_key: [u8; 64], + pub proof: [u8; 32], } pub fn result_migrate_success_to_result( result: Result, ) -> MigrateResult { match result { - Ok(MigrateSuccess { output }) => { + Ok(MigrateSuccess { + output, + new_contract_key, + proof, + }) => { let user_buffer = unsafe { let mut user_buffer = std::mem::MaybeUninit::::uninit(); match ocall_allocate(user_buffer.as_mut_ptr(), output.as_ptr(), output.len()) { @@ -107,6 +113,8 @@ pub fn result_migrate_success_to_result( }; MigrateResult::Success { output: user_buffer, + new_contract_key, + proof, } } Err(err) => MigrateResult::Failure { err }, diff --git a/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs b/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs index 97e13fa6d..46c07de71 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs @@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize}; use cw_types_v010::encoding::Binary; use cw_types_v010::types as v010types; -use cw_types_v010::types::{Env as V010Env, HumanAddr}; +use cw_types_v010::types::{ContractKeyWithProof, Env as V010Env, HumanAddr}; use cw_types_v1::types as v1types; use cw_types_v1::types::Env as V1Env; use cw_types_v1::types::MessageInfo as V1MessageInfo; @@ -41,7 +41,7 @@ pub struct BaseEnv(pub V010Env); impl BaseEnv { pub fn get_contract_key(&self) -> Result<[u8; CONTRACT_KEY_LENGTH], EnclaveError> { let contract_key = if let Some(b64_key) = &self.0.contract_key { - base64::decode(b64_key).map_err(|err| { + base64::decode(&b64_key.key).map_err(|err| { warn!( "got an error while trying to decode contract key {:?}: {}", b64_key, err @@ -64,6 +64,22 @@ impl BaseEnv { Ok(key_as_bytes) } + pub fn was_migrated(&self) -> bool { + if let Some(key) = &self.0.contract_key { + key.original.is_some() + } else { + false + } + } + + pub fn get_original_contract_key(&self) -> Option { + if let Some(key) = &self.0.contract_key { + key.original.clone() + } else { + None + } + } + pub fn get_verification_params(&self) -> (&BaseAddr, &BaseAddr, u64, &Vec) { ( &self.0.message.sender, diff --git a/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/types.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/types.rs index 30baacaad..045e7f30c 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/types.rs @@ -92,12 +92,34 @@ impl fmt::Display for CanonicalAddr { } } +#[derive(Serialize, Deserialize, Clone, Default, Debug, PartialEq)] +pub struct ContractKey { + pub key: String, + pub original: Option, +} + +#[derive(Serialize, Deserialize, Clone, Default, Debug, PartialEq)] +pub struct ContractKeyWithProof { + pub key: String, + pub proof: [u8; 32], +} + +impl ContractKeyWithProof { + pub fn get_key(&self) -> [u8; 64] { + let mut output = [0u8; 64]; + let decoded = base64::decode(&self.key).unwrap(); + output.copy_from_slice(&decoded); + + output + } +} + #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] pub struct Env { pub block: BlockInfo, pub message: MessageInfo, pub contract: ContractInfo, - pub contract_key: Option, + pub contract_key: Option, #[serde(default)] pub contract_code_hash: String, #[serde(default)] diff --git a/cosmwasm/packages/sgx-vm/src/wasmi/results.rs b/cosmwasm/packages/sgx-vm/src/wasmi/results.rs index 1cde197a8..a6eadc5a9 100644 --- a/cosmwasm/packages/sgx-vm/src/wasmi/results.rs +++ b/cosmwasm/packages/sgx-vm/src/wasmi/results.rs @@ -37,8 +37,14 @@ pub fn init_result_to_vm_result(other: InitResult) -> VmResult { pub fn migrate_result_to_vm_result(other: MigrateResult) -> VmResult { match other { - MigrateResult::Success { output } => Ok(MigrateSuccess { + MigrateResult::Success { + output, + new_contract_key, + proof, + } => Ok(MigrateSuccess { output: unsafe { exports::recover_buffer(output) }.unwrap_or_else(Vec::new), + new_contract_key, + proof, }), MigrateResult::Failure { err } => Err(err.into()), } @@ -48,11 +54,16 @@ pub fn migrate_result_to_vm_result(other: MigrateResult) -> VmResult, + new_contract_key: [u8; 64], + proof: [u8; 32], } impl MigrateSuccess { pub fn into_output(self) -> Vec { - self.output + let mut out_vec = self.new_contract_key.to_vec(); + out_vec.extend_from_slice(&self.proof); + out_vec.extend_from_slice(&self.output); + out_vec } } diff --git a/go-cosmwasm/api/bindings.h b/go-cosmwasm/api/bindings.h index 536e9da37..69e984da1 100644 --- a/go-cosmwasm/api/bindings.h +++ b/go-cosmwasm/api/bindings.h @@ -197,6 +197,20 @@ Buffer instantiate(cache_t *cache, Buffer key_gen(Buffer *err); +Buffer migrate(cache_t *cache, + Buffer contract_id, + Buffer params, + Buffer msg, + DB db, + GoApi api, + GoQuerier querier, + uint64_t gas_limit, + uint64_t *gas_used, + Buffer *err, + Buffer sig_info, + Buffer admin, + Buffer admin_proof); + Buffer query(cache_t *cache, Buffer code_id, Buffer params, diff --git a/go-cosmwasm/api/lib_mock.go b/go-cosmwasm/api/lib_mock.go index f183e2c8a..c94892f8d 100644 --- a/go-cosmwasm/api/lib_mock.go +++ b/go-cosmwasm/api/lib_mock.go @@ -95,6 +95,23 @@ func GetCode(cache Cache, code_id []byte) ([]byte, error) { return nil, nil } +func Migrate( + cache Cache, + code_id []byte, + params []byte, + msg []byte, + gasMeter *GasMeter, + store KVStore, + api *GoAPI, + querier *Querier, + gasLimit uint64, + sigInfo []byte, + admin []byte, + adminProof []byte, +) ([]byte, uint64, error) { + return nil, 0, nil +} + func Instantiate( cache Cache, code_id []byte, diff --git a/go-cosmwasm/lib.go b/go-cosmwasm/lib.go index d4f83ca50..6c016e57d 100644 --- a/go-cosmwasm/lib.go +++ b/go-cosmwasm/lib.go @@ -418,28 +418,32 @@ func (w *Wasmer) Migrate( admin sdk.AccAddress, adminProof []byte, // data, contractKey, adminProof, gasUsed, error -) (interface{}, uint64, error) { +) (interface{}, []byte, []byte, uint64, error) { paramBin, err := json.Marshal(env) if err != nil { - return nil, 0, err + return nil, nil, nil, 0, err } sigInfoBin, err := json.Marshal(sigInfo) if err != nil { - return nil, 0, err + return nil, nil, nil, 0, err } data, gasUsed, err := api.Migrate(w.cache, newCodeId, paramBin, migrateMsg, &gasMeter, store, &goapi, &querier, gasLimit, sigInfoBin, admin, adminProof) if err != nil { - return nil, gasUsed, err + return nil, nil, nil, gasUsed, err } + newContractKey := data[0:64] + proof := data[64:96] + data = data[96:] + var respV010orV1 V010orV1ContractInitResponse err = json.Unmarshal(data, &respV010orV1) if err != nil { // unidentified response 🤷 - return nil, gasUsed, fmt.Errorf("migrate: cannot parse response from json: %w", err) + return nil, nil, nil, gasUsed, fmt.Errorf("migrate: cannot parse response from json: %w", err) } isOutputAddressedToReply := len(respV010orV1.InternaReplyEnclaveSig) > 0 && len(respV010orV1.InternalMsgId) > 0 @@ -451,18 +455,18 @@ func (w *Wasmer) Migrate( InternalMsgId: respV010orV1.InternalMsgId, InternaReplyEnclaveSig: respV010orV1.InternaReplyEnclaveSig, Data: []byte(respV010orV1.V010.Err.GenericErr.Msg), - }, gasUsed, fmt.Errorf("%+v", respV010orV1.V010.Err) + }, nil, nil, gasUsed, fmt.Errorf("%+v", respV010orV1.V010.Err) } if respV010orV1.V010.Ok != nil { if isOutputAddressedToReply { respV010orV1.V010.Ok.Data, err = AppendReplyInternalDataToData(respV010orV1.V010.Ok.Data, respV010orV1.InternaReplyEnclaveSig, respV010orV1.InternalMsgId) if err != nil { - return nil, gasUsed, fmt.Errorf("cannot serialize v0.10 DataWithInternalReplyInfo into binary : %w", err) + return nil, nil, nil, gasUsed, fmt.Errorf("cannot serialize v0.10 DataWithInternalReplyInfo into binary : %w", err) } } - return respV010orV1.V010.Ok, gasUsed, nil + return respV010orV1.V010.Ok, newContractKey, proof, gasUsed, nil } } @@ -473,20 +477,20 @@ func (w *Wasmer) Migrate( InternalMsgId: respV010orV1.InternalMsgId, InternaReplyEnclaveSig: respV010orV1.InternaReplyEnclaveSig, Data: []byte(respV010orV1.V1.Err.GenericErr.Msg), - }, gasUsed, fmt.Errorf("%+v", respV010orV1.V1.Err) + }, nil, nil, gasUsed, fmt.Errorf("%+v", respV010orV1.V1.Err) } if respV010orV1.V1.Ok != nil { if isOutputAddressedToReply { respV010orV1.V1.Ok.Data, err = AppendReplyInternalDataToData(respV010orV1.V1.Ok.Data, respV010orV1.InternaReplyEnclaveSig, respV010orV1.InternalMsgId) if err != nil { - return nil, gasUsed, fmt.Errorf("cannot serialize v1 DataWithInternalReplyInfo into binary: %w", err) + return nil, nil, nil, gasUsed, fmt.Errorf("cannot serialize v1 DataWithInternalReplyInfo into binary: %w", err) } } - return respV010orV1.V1.Ok, gasUsed, nil + return respV010orV1.V1.Ok, newContractKey, proof, gasUsed, nil } } - return nil, gasUsed, fmt.Errorf("instantiate: cannot detect response type (v0.10 or v1)") + return nil, nil, nil, gasUsed, fmt.Errorf("instantiate: cannot detect response type (v0.10 or v1)") } diff --git a/go-cosmwasm/types/env.go b/go-cosmwasm/types/env.go index 1adcc6423..ed8191ab6 100644 --- a/go-cosmwasm/types/env.go +++ b/go-cosmwasm/types/env.go @@ -11,11 +11,21 @@ type Env struct { Block BlockInfo `json:"block"` Message MessageInfo `json:"message"` Contract ContractInfo `json:"contract"` - Key ContractKey `json:"contract_key"` + Key *ContractKey `json:"contract_key,omitempty"` QueryDepth uint32 `json:"query_depth"` Transaction *TransactionInfo `json:"transaction,omitempty"` } +type ContractKey struct { + Key []byte `json:"key"` + Original ContractKeyWithProof `json:"original,omitempty"` +} + +type ContractKeyWithProof struct { + Key []byte `json:"key"` + Proof []byte `json:"proof"` +} + type TransactionInfo struct { // Position of this transaction in the block. // The first transaction has index 0 @@ -29,8 +39,6 @@ type BaseEnv[T Env] struct { First T } -type ContractKey string - type BlockInfo struct { // block height this transaction is executed Height uint64 `json:"height"` diff --git a/proto/secret/compute/v1beta1/query.proto b/proto/secret/compute/v1beta1/query.proto index 1ae0acdce..094b9cb62 100644 --- a/proto/secret/compute/v1beta1/query.proto +++ b/proto/secret/compute/v1beta1/query.proto @@ -158,6 +158,7 @@ message DecryptedAnswers { // QueryContractHistoryRequest is the request type for the Query/ContractHistory // RPC method message QueryContractHistoryRequest { + option (gogoproto.equal) = false; // address is the address of the contract to query string contract_address = 1; // pagination defines an optional pagination for the request. @@ -167,6 +168,8 @@ message QueryContractHistoryRequest { // QueryContractHistoryResponse is the response type for the // Query/ContractHistory RPC method message QueryContractHistoryResponse { + option (gogoproto.equal) = false; + repeated ContractCodeHistoryEntry entries = 1 [ (gogoproto.nullable) = false ]; // pagination defines the pagination in the response. diff --git a/proto/secret/compute/v1beta1/types.proto b/proto/secret/compute/v1beta1/types.proto index 0ec11d516..5737bca7b 100644 --- a/proto/secret/compute/v1beta1/types.proto +++ b/proto/secret/compute/v1beta1/types.proto @@ -34,6 +34,16 @@ message ContractCustomInfo { string label = 2; } +message ContractKey { + bytes key = 1; + ContractKeyWithProof original = 2; +} + +message ContractKeyWithProof { + bytes key = 1; + bytes proof = 2; +} + // ContractInfo stores a WASM contract instance message ContractInfo { // CodeID is the reference to the stored Wasm code @@ -46,7 +56,7 @@ message ContractInfo { AbsoluteTxPosition created = 5; string ibc_port_id = 6 [ (gogoproto.customname) = "IBCPortID" ]; // Admin is an optional address that can execute migrations - string admin = 7; + bytes admin = 7 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"]; // Proof that enclave executed the instantiate command bytes admin_proof = 8; } diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index a1f14d781..784719f6e 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -528,8 +528,6 @@ func (k Keeper) Execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller return nil, err } - store := ctx.KVStore(k.storeKey) - // add more funds if !coins.IsZero() { if k.bankKeeper.BlockedAddr(caller) { @@ -543,8 +541,13 @@ func (k Keeper) Execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller } random := k.GetRandomSeed(ctx, ctx.BlockHeight()) - contractKey := store.Get(types.GetContractEnclaveKey(contractAddress)) - env := types.NewEnv(ctx, caller, coins, contractAddress, contractKey, random) + + contractKey, err := k.GetContractKey(ctx, contractAddress) + if err != nil { + return nil, err + } + + env := types.NewEnv(ctx, caller, coins, contractAddress, &contractKey, random) // prepare querier querier := QueryHandler{ @@ -635,16 +638,17 @@ func (k Keeper) querySmartImpl(ctx sdk.Context, contractAddress sdk.AccAddress, Caller: contractAddress, } - store := ctx.KVStore(k.storeKey) - // 0x01 | codeID (uint64) -> ContractInfo - contractKey := store.Get(types.GetContractEnclaveKey(contractAddress)) + contractKey, err := k.GetContractKey(ctx, contractAddress) + if err != nil { + return nil, err + } params := types.NewEnv( ctx, sdk.AccAddress{}, /* empty because it's unused in queries */ sdk.NewCoins(), /* empty because it's unused in queries */ contractAddress, - contractKey, + &contractKey, []byte{0}, /* empty because it's unused in queries */ ) params.QueryDepth = queryDepth @@ -700,12 +704,29 @@ func (k Keeper) contractInstance(ctx sdk.Context, contractAddress sdk.AccAddress return contract, codeInfo, prefixStore, nil } -func (k Keeper) GetContractKey(ctx sdk.Context, contractAddress sdk.AccAddress) []byte { +func (k Keeper) GetContractKey(ctx sdk.Context, contractAddress sdk.AccAddress) (types.ContractKey, error) { store := ctx.KVStore(k.storeKey) - contractKey := store.Get(types.GetContractEnclaveKey(contractAddress)) + var contractKey types.ContractKey + contractKeyBz := store.Get(types.GetContractEnclaveKey(contractAddress)) - return contractKey + if contractKeyBz == nil { + return types.ContractKey{}, sdkerrors.Wrap(types.ErrNotFound, "contract key") + } + + err := k.cdc.Unmarshal(contractKeyBz, &contractKey) + if err != nil { + return contractKey, err + } + + return contractKey, nil +} + +func (k Keeper) SetContractKey(ctx sdk.Context, contractAddress sdk.AccAddress, contractKey *types.ContractKey) { + store := ctx.KVStore(k.storeKey) + + contractKeyBz := k.cdc.MustMarshal(contractKey) + store.Set(types.GetContractEnclaveKey(contractAddress), contractKeyBz) } func (k Keeper) GetRandomSeed(ctx sdk.Context, height int64) []byte { @@ -873,10 +894,10 @@ func (k *Keeper) handleContractResponse( logs []v010wasmTypes.LogAttribute, evts v1wasmTypes.Events, data []byte, -// original TX in order to extract the first 64bytes of signing info + // original TX in order to extract the first 64bytes of signing info ogTx []byte, -// sigInfo of the initial message that triggered the original contract call -// This is used mainly in replies in order to decrypt their data. + // sigInfo of the initial message that triggered the original contract call + // This is used mainly in replies in order to decrypt their data. ogSigInfo wasmTypes.VerificationInfo, ogCosmosMessageVersion wasmTypes.CosmosMsgVersion, ) ([]byte, error) { @@ -1047,12 +1068,14 @@ func (k Keeper) reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply v1w // always consider this pinned ctx.GasMeter().ConsumeGas(types.InstanceCost, "Loading Compute module: reply") - store := ctx.KVStore(k.storeKey) - contractKey := store.Get(types.GetContractEnclaveKey(contractAddress)) + contractKey, err := k.GetContractKey(ctx, contractAddress) + if err != nil { + return nil, err + } random := k.GetRandomSeed(ctx, ctx.BlockHeight()) - env := types.NewEnv(ctx, contractAddress, sdk.Coins{}, contractAddress, contractKey, random) + env := types.NewEnv(ctx, contractAddress, sdk.Coins{}, contractAddress, &contractKey, random) // prepare querier querier := QueryHandler{ @@ -1152,13 +1175,16 @@ func (k Keeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller contractInfo.IBCPortID = ibcPort } - store := ctx.KVStore(k.storeKey) - contractKey := store.Get(types.GetContractEnclaveKey(contractAddress)) + contractKey, err := k.GetContractKey(ctx, contractAddress) + if err != nil { + return nil, err + } + random := k.GetRandomSeed(ctx, ctx.BlockHeight()) - env := types.NewEnv(ctx, caller, sdk.Coins{}, contractAddress, contractKey, random) + env := types.NewEnv(ctx, caller, sdk.Coins{}, contractAddress, &contractKey, random) - adminProof := k.GetContractInfo(ctx, contractAddress).Admin //Proof + adminProof := k.GetContractInfo(ctx, contractAddress).AdminProof admin := k.GetContractInfo(ctx, contractAddress).Admin // prepare querier @@ -1171,9 +1197,18 @@ func (k Keeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller // instantiate wasm contract gas := gasForContract(ctx) - response, gasUsed, err := k.wasmer.Migrate(newCodeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, gasMeter(ctx), gas, verificationInfo, admin, adminProof) + response, newContractKey, proof, gasUsed, err := k.wasmer.Migrate(newCodeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, gasMeter(ctx), gas, verificationInfo, admin, adminProof) consumeGas(ctx, gasUsed) + // update contract key with new one + k.SetContractKey(ctx, contractAddress, &types.ContractKey{ + Key: newContractKey, + Original: &types.ContractKeyWithProof{ + Key: contractKey.Key, + Proof: proof, + }, + }) + if err != nil { var result []byte switch res := response.(type) { //nolint:gocritic diff --git a/x/compute/internal/keeper/legacy_querier.go b/x/compute/internal/keeper/legacy_querier.go index 4abafab0e..8da82ec10 100644 --- a/x/compute/internal/keeper/legacy_querier.go +++ b/x/compute/internal/keeper/legacy_querier.go @@ -135,10 +135,10 @@ func queryContractState(ctx sdk.Context, bech, queryMethod string, data []byte, } func queryContractKey(ctx sdk.Context, address sdk.AccAddress, keeper Keeper) ([]byte, error) { - res := keeper.GetContractKey(ctx, address) - if res == nil { + res, err := keeper.GetContractKey(ctx, address) + if err != nil { return nil, nil } - return res, nil + return res.Key, nil } diff --git a/x/compute/internal/keeper/querier.go b/x/compute/internal/keeper/querier.go index 6bb770c69..f20d8cc6f 100644 --- a/x/compute/internal/keeper/querier.go +++ b/x/compute/internal/keeper/querier.go @@ -18,6 +18,11 @@ type GrpcQuerier struct { keeper Keeper } +func (q GrpcQuerier) ContractHistory(ctx context.Context, request *types.QueryContractHistoryRequest) (*types.QueryContractHistoryResponse, error) { + //TODO implement me + panic("implement me") +} + func NewGrpcQuerier(keeper Keeper) GrpcQuerier { return GrpcQuerier{keeper: keeper} } diff --git a/x/compute/internal/keeper/relay.go b/x/compute/internal/keeper/relay.go index ee3905b0a..960d5e4fd 100644 --- a/x/compute/internal/keeper/relay.go +++ b/x/compute/internal/keeper/relay.go @@ -29,16 +29,18 @@ func (k Keeper) ibcContractCall(ctx sdk.Context, return "", err } - store := ctx.KVStore(k.storeKey) + contractKey, err := k.GetContractKey(ctx, contractAddress) + if err != nil { + return nil, err + } + random := k.GetRandomSeed(ctx, ctx.BlockHeight()) - contractKey := store.Get(types.GetContractEnclaveKey(contractAddress)) - random := store.Get(types.GetRandomKey(ctx.BlockHeight())) env := types.NewEnv( ctx, sdk.AccAddress{}, /* there's no MessageInfo for IBC contract calls */ sdk.NewCoins(), /* there's no MessageInfo for IBC contract calls */ contractAddress, - contractKey, + &contractKey, random, ) diff --git a/x/compute/internal/types/query.pb.go b/x/compute/internal/types/query.pb.go index 62ccd47db..85895444a 100644 --- a/x/compute/internal/types/query.pb.go +++ b/x/compute/internal/types/query.pb.go @@ -757,87 +757,87 @@ func init() { } var fileDescriptor_7735281c5fa969d4 = []byte{ - // 1278 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x57, 0xcf, 0x6f, 0x1b, 0x45, + // 1279 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x57, 0x4d, 0x6c, 0x1b, 0x45, 0x14, 0xf6, 0xb4, 0x4e, 0xd2, 0xbc, 0xa4, 0x49, 0x3a, 0xa4, 0xa9, 0xeb, 0x14, 0xa7, 0x5d, 0x4a, - 0xf3, 0xab, 0x78, 0x6b, 0x27, 0x14, 0xa9, 0xe2, 0x92, 0xa4, 0x81, 0x06, 0x05, 0x28, 0xee, 0x01, - 0x09, 0x15, 0x59, 0xe3, 0xf5, 0xc4, 0x5e, 0xd5, 0xd9, 0x71, 0x77, 0xc6, 0x4d, 0x2c, 0x14, 0x0e, - 0x9c, 0x38, 0x56, 0x02, 0x24, 0x04, 0x17, 0x4e, 0x50, 0x71, 0x40, 0xe2, 0x08, 0x7f, 0x41, 0x0e, - 0x1c, 0x22, 0x71, 0xe1, 0x54, 0x41, 0xc2, 0x01, 0x71, 0xe7, 0x8e, 0x76, 0x66, 0x76, 0xb3, 0x6b, - 0xaf, 0x63, 0x3b, 0x1c, 0xb8, 0xed, 0xcc, 0xbc, 0xf7, 0xbe, 0xef, 0xbd, 0x37, 0xf3, 0xde, 0x5b, - 0x30, 0x38, 0xb5, 0x5c, 0x2a, 0x4c, 0x8b, 0x6d, 0xd7, 0x1b, 0x82, 0x9a, 0x4f, 0x72, 0x25, 0x2a, - 0x48, 0xce, 0x7c, 0xdc, 0xa0, 0x6e, 0x33, 0x5b, 0x77, 0x99, 0x60, 0x78, 0x4a, 0xc9, 0x64, 0xb5, - 0x4c, 0x56, 0xcb, 0xa4, 0x27, 0x2b, 0xac, 0xc2, 0xa4, 0x88, 0xe9, 0x7d, 0x29, 0xe9, 0x74, 0x27, - 0x8b, 0xa2, 0x59, 0xa7, 0x5c, 0xcb, 0x4c, 0x57, 0x18, 0xab, 0xd4, 0xa8, 0x29, 0x57, 0xa5, 0xc6, - 0x96, 0x49, 0xb7, 0xeb, 0x42, 0xc3, 0xa5, 0xaf, 0xe8, 0x43, 0x52, 0xb7, 0x4d, 0xe2, 0x38, 0x4c, - 0x10, 0x61, 0x33, 0xc7, 0x57, 0x7d, 0xc9, 0x62, 0x7c, 0x9b, 0x71, 0xb3, 0x44, 0x38, 0x35, 0x49, - 0xc9, 0xb2, 0x03, 0x00, 0x6f, 0xa1, 0x85, 0x16, 0xc2, 0x42, 0xd2, 0x95, 0x40, 0xaa, 0x4e, 0x2a, - 0xb6, 0x23, 0x2d, 0x2a, 0x59, 0xe3, 0x43, 0x48, 0xbf, 0xe7, 0x49, 0x3c, 0x90, 0xb4, 0xd7, 0x98, - 0x23, 0x5c, 0x62, 0x89, 0x02, 0x7d, 0xdc, 0xa0, 0x5c, 0xe0, 0x79, 0x98, 0xb0, 0xf4, 0x56, 0x91, - 0x94, 0xcb, 0x2e, 0xe5, 0x3c, 0x85, 0xae, 0xa2, 0xb9, 0xe1, 0xc2, 0xb8, 0xbf, 0xbf, 0xa2, 0xb6, - 0xf1, 0x24, 0x0c, 0x48, 0xa8, 0xd4, 0x99, 0xab, 0x68, 0x6e, 0xb4, 0xa0, 0x16, 0xc6, 0x22, 0xbc, - 0x20, 0xcd, 0xaf, 0x36, 0x37, 0x49, 0x89, 0xd6, 0x7c, 0xbb, 0x93, 0x30, 0x50, 0xf3, 0xd6, 0xda, - 0x98, 0x5a, 0x18, 0x6f, 0xc1, 0x8b, 0x5a, 0x78, 0x2d, 0x6a, 0xbc, 0x7f, 0x3a, 0x86, 0x09, 0x93, - 0x81, 0xad, 0x32, 0xdd, 0x28, 0xfb, 0x26, 0x2e, 0xc1, 0x90, 0xc5, 0xca, 0xb4, 0x68, 0x97, 0xa5, - 0x66, 0xb2, 0x30, 0x68, 0xc9, 0x73, 0x23, 0x07, 0xd3, 0xb1, 0x81, 0xe0, 0x75, 0xe6, 0x70, 0x8a, - 0x31, 0x24, 0xcb, 0x44, 0x10, 0xa9, 0x34, 0x5a, 0x90, 0xdf, 0xc6, 0x57, 0x08, 0x2e, 0x4b, 0x1d, - 0x5f, 0x7a, 0xc3, 0xd9, 0x62, 0x81, 0x46, 0x1f, 0xb1, 0x2b, 0xc0, 0x68, 0xd8, 0x84, 0x0c, 0xe1, - 0x48, 0xfe, 0x7a, 0x36, 0xfe, 0xe6, 0x65, 0xc3, 0xb2, 0xab, 0xe7, 0x0e, 0x9e, 0xcf, 0xa0, 0xbf, - 0x9f, 0xcf, 0x24, 0x0a, 0x11, 0x1b, 0xc6, 0x97, 0x08, 0x2e, 0x85, 0x37, 0xde, 0xb7, 0x45, 0xd5, - 0xc7, 0xfb, 0x9f, 0xa9, 0x7d, 0x0c, 0x99, 0x48, 0xd8, 0xf8, 0x71, 0x92, 0x74, 0xec, 0x1e, 0xc2, - 0x58, 0x40, 0xd0, 0x76, 0xb6, 0x98, 0x47, 0xef, 0xec, 0xdc, 0x48, 0xde, 0xec, 0x05, 0x37, 0xe4, - 0xe9, 0x6a, 0x72, 0xdf, 0x83, 0x3f, 0x6f, 0x85, 0x8e, 0xb9, 0xf1, 0x39, 0x82, 0x09, 0x09, 0x18, - 0x4e, 0x57, 0xa7, 0x8b, 0x81, 0x53, 0x30, 0x64, 0xb9, 0x94, 0x08, 0xe6, 0x4a, 0xe7, 0x87, 0x0b, - 0xfe, 0x12, 0x4f, 0xc3, 0xb0, 0x54, 0xa9, 0x12, 0x5e, 0x4d, 0x9d, 0x95, 0x67, 0xe7, 0xbc, 0x8d, - 0x7b, 0x84, 0x57, 0xf1, 0x14, 0x0c, 0x72, 0xd6, 0x70, 0x2d, 0x9a, 0x4a, 0xca, 0x13, 0xbd, 0xf2, - 0xcc, 0x95, 0x1a, 0x76, 0xad, 0x4c, 0xdd, 0xd4, 0x80, 0x32, 0xa7, 0x97, 0xc6, 0x2e, 0x5c, 0xd0, - 0x61, 0x29, 0xd3, 0x80, 0xd6, 0xbb, 0x1a, 0xc3, 0x8b, 0x82, 0x24, 0x36, 0x92, 0x9f, 0xeb, 0x1c, - 0x84, 0xa8, 0x4f, 0xa1, 0x04, 0x48, 0x5e, 0xde, 0x99, 0x77, 0x91, 0x77, 0x08, 0xdf, 0xd6, 0xcf, - 0x54, 0x7e, 0x1b, 0x16, 0xe0, 0x00, 0x99, 0x07, 0xd0, 0x6f, 0x03, 0x04, 0xd0, 0x7e, 0x02, 0x7a, - 0xc7, 0x56, 0x91, 0x1f, 0xf6, 0x71, 0xb9, 0xb1, 0x01, 0x57, 0x22, 0x59, 0x0f, 0xde, 0x76, 0xdf, - 0xef, 0xc5, 0xc8, 0xeb, 0xa2, 0xe5, 0x9b, 0xd2, 0xb5, 0x45, 0x1b, 0x8a, 0x2f, 0x2e, 0xcb, 0x70, - 0x31, 0xf0, 0xd1, 0x4b, 0x50, 0x20, 0x1e, 0xc9, 0x22, 0x8a, 0x66, 0xd1, 0xf8, 0x02, 0xc1, 0xf8, - 0x5d, 0x6a, 0xb9, 0xcd, 0xba, 0xa0, 0xe5, 0x15, 0x87, 0xef, 0x50, 0xd7, 0x8b, 0xa0, 0x57, 0xcd, - 0xb5, 0xac, 0xfc, 0xf6, 0x30, 0x6d, 0xa7, 0xde, 0x10, 0xfa, 0x8a, 0xa8, 0x05, 0x9e, 0x81, 0x11, - 0xd6, 0x10, 0xf5, 0x86, 0x28, 0xca, 0xda, 0xa1, 0xae, 0x08, 0xa8, 0xad, 0xbb, 0x44, 0x10, 0x9c, - 0x83, 0x8b, 0x21, 0x81, 0x22, 0xe1, 0x45, 0x2e, 0x5c, 0xdb, 0xa9, 0xe8, 0x3b, 0x83, 0x8f, 0x45, - 0x57, 0xf8, 0x03, 0x79, 0x72, 0x27, 0xf9, 0xd7, 0x37, 0x33, 0x09, 0xe3, 0x1f, 0x04, 0x13, 0x2d, - 0xbc, 0x38, 0x5e, 0x81, 0x21, 0xa2, 0x3e, 0x75, 0xb6, 0x66, 0x3b, 0x65, 0xab, 0x45, 0xb5, 0xe0, - 0xeb, 0xe1, 0xcd, 0x80, 0x71, 0x8d, 0x55, 0x78, 0xea, 0x8c, 0x34, 0xf3, 0x72, 0x56, 0x35, 0x94, - 0xac, 0xd7, 0x50, 0xb2, 0xb2, 0xd1, 0xf8, 0x86, 0x14, 0xa9, 0xf5, 0x27, 0xd4, 0x11, 0x3a, 0xe3, - 0xda, 0xbd, 0x4d, 0x56, 0xe1, 0xf8, 0x1a, 0x8c, 0x6a, 0x6b, 0xd4, 0x75, 0x99, 0xab, 0x03, 0xa0, - 0x11, 0xd6, 0xbd, 0x2d, 0x3c, 0x0b, 0xe3, 0xf5, 0x1a, 0xb1, 0x1d, 0x41, 0x77, 0x7d, 0x29, 0xe5, - 0xfb, 0x58, 0xb0, 0x2d, 0x05, 0xb5, 0xdf, 0x4f, 0x91, 0x2e, 0xd3, 0x7e, 0xea, 0xef, 0xd9, 0x5c, - 0x30, 0xb7, 0x79, 0x8a, 0x86, 0xf5, 0x06, 0xc0, 0x71, 0x37, 0xd4, 0x75, 0xed, 0x46, 0xc4, 0x53, - 0x35, 0x05, 0xf8, 0xae, 0xde, 0x27, 0x15, 0xaa, 0x61, 0x0a, 0x21, 0x4d, 0xe3, 0x27, 0xd4, 0x72, - 0xb1, 0x03, 0x4a, 0xfa, 0x82, 0xdd, 0x87, 0x21, 0xea, 0x08, 0xd7, 0xa6, 0x7e, 0x5a, 0x6e, 0x75, - 0xab, 0x62, 0xf2, 0x8e, 0x2a, 0x2b, 0xeb, 0x8e, 0x70, 0x9b, 0x3a, 0xb4, 0xbe, 0x19, 0xfc, 0x66, - 0x0c, 0xf5, 0xd9, 0xae, 0xd4, 0x15, 0x9d, 0x30, 0xf7, 0xfc, 0xd7, 0xe7, 0x61, 0x40, 0x72, 0xc7, - 0xdf, 0xa3, 0x68, 0xa1, 0xc7, 0xaf, 0x76, 0x22, 0x79, 0x62, 0x8b, 0x4e, 0xe7, 0x4e, 0x54, 0x8b, - 0x6b, 0x94, 0xc6, 0xad, 0x4f, 0x7e, 0xfd, 0xf3, 0xb3, 0x33, 0x0b, 0x78, 0xae, 0x6d, 0x68, 0xf2, - 0x2a, 0x8f, 0xf9, 0x51, 0x6b, 0x42, 0xf7, 0xf0, 0x77, 0x08, 0x2e, 0xb4, 0x35, 0x0f, 0x7c, 0xb3, - 0x2b, 0xe3, 0xd0, 0x20, 0x90, 0xbe, 0xdd, 0x13, 0xd1, 0xb6, 0xd6, 0x64, 0xdc, 0x94, 0x6c, 0x6f, - 0xe0, 0xeb, 0x6d, 0x6c, 0x7d, 0x9e, 0xdc, 0xa3, 0x2c, 0x3b, 0xc9, 0x1e, 0xfe, 0x11, 0xe9, 0x01, - 0x28, 0x3a, 0x56, 0xe0, 0xfc, 0x89, 0xe8, 0xb1, 0xc3, 0x58, 0x7a, 0xa9, 0x2f, 0x1d, 0x4d, 0x37, - 0x27, 0xe9, 0x2e, 0xe2, 0xf9, 0xf8, 0x19, 0x37, 0x2e, 0xba, 0x9f, 0x22, 0x48, 0x7a, 0x4e, 0xf7, - 0x19, 0xd0, 0xf9, 0x2e, 0x01, 0x3d, 0x6e, 0x6a, 0xc6, 0xac, 0x24, 0x75, 0x0d, 0xcf, 0xc4, 0xc4, - 0xb0, 0x4c, 0x43, 0xe1, 0x7b, 0x04, 0x03, 0xb2, 0x27, 0xe1, 0xa9, 0xac, 0x1a, 0x8b, 0xb3, 0xfe, - 0xcc, 0x9c, 0x5d, 0xf7, 0x66, 0xe6, 0xf4, 0x42, 0x57, 0xd0, 0xa0, 0xc1, 0x18, 0x19, 0x89, 0x9a, - 0xc2, 0x53, 0xb1, 0xa8, 0x1c, 0xff, 0x82, 0xe0, 0xb2, 0xdf, 0x1d, 0xda, 0xee, 0xf7, 0x69, 0xdf, - 0xc3, 0x2b, 0x5d, 0x09, 0x86, 0x9b, 0x91, 0xb1, 0x21, 0x39, 0xae, 0xe1, 0x95, 0x58, 0x8e, 0xb2, - 0x47, 0x99, 0xa5, 0x66, 0xb1, 0x35, 0x69, 0x71, 0x69, 0x7c, 0xa6, 0xa7, 0x1c, 0xdf, 0x9d, 0x53, - 0xbc, 0x91, 0x3e, 0xc9, 0xbf, 0x26, 0xc9, 0xe7, 0xb0, 0xd9, 0x8d, 0xbc, 0xcc, 0x6e, 0x28, 0xcd, - 0x3f, 0x20, 0x18, 0x93, 0x3d, 0x7c, 0xb5, 0xf9, 0x1f, 0xc3, 0x9d, 0xef, 0xe9, 0x55, 0x47, 0xe6, - 0x85, 0x13, 0x9e, 0x88, 0x9c, 0x1c, 0xe2, 0x62, 0xfb, 0x2d, 0x82, 0x31, 0x7f, 0xc4, 0x54, 0x7f, - 0x36, 0x78, 0xb1, 0x0b, 0xe1, 0xf0, 0xff, 0x4f, 0x7a, 0xb9, 0x27, 0x9a, 0x2d, 0x13, 0xd2, 0x09, - 0x44, 0xdb, 0xef, 0x83, 0xa4, 0xbe, 0x87, 0x7f, 0x46, 0x30, 0xde, 0xd2, 0x97, 0xf0, 0x52, 0x4f, - 0xe0, 0xd1, 0xc6, 0xda, 0x23, 0xe3, 0x96, 0xd6, 0x67, 0xbc, 0x2e, 0x19, 0xdf, 0xc6, 0xcb, 0x9d, - 0x19, 0x57, 0x95, 0x4a, 0x4c, 0x94, 0x57, 0x1f, 0xee, 0xff, 0x91, 0x49, 0x3c, 0x3b, 0xcc, 0xa0, - 0xfd, 0xc3, 0x0c, 0x3a, 0x38, 0xcc, 0xa0, 0xdf, 0x0f, 0x33, 0xe8, 0xe9, 0x51, 0x26, 0x71, 0x70, - 0x94, 0x49, 0xfc, 0x76, 0x94, 0x49, 0x7c, 0x70, 0xa7, 0x62, 0x8b, 0x6a, 0xa3, 0xe4, 0x91, 0x32, - 0xb9, 0xe5, 0x8a, 0x1a, 0x29, 0x71, 0x53, 0x55, 0xc2, 0x77, 0xa8, 0xd8, 0x61, 0xee, 0x23, 0x73, - 0x37, 0x80, 0xf6, 0xa6, 0x09, 0xd7, 0x21, 0x35, 0xf5, 0x2f, 0x5e, 0x1a, 0x94, 0xa5, 0x64, 0xe9, - 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x29, 0x89, 0x0c, 0x2d, 0x04, 0x10, 0x00, 0x00, + 0xf3, 0x57, 0xbc, 0xb5, 0x13, 0x8a, 0x54, 0x71, 0x49, 0xd2, 0x40, 0x83, 0x02, 0x14, 0xf7, 0x80, + 0x84, 0x8a, 0xac, 0xf1, 0x7a, 0x62, 0xaf, 0xea, 0xec, 0xb8, 0x3b, 0xe3, 0x26, 0x16, 0x0a, 0x07, + 0x4e, 0x1c, 0x91, 0xf8, 0x11, 0x82, 0x0b, 0x27, 0xa8, 0x38, 0x20, 0x71, 0xe5, 0xc2, 0x35, 0x07, + 0x0e, 0x91, 0xb8, 0x70, 0xaa, 0x20, 0xe1, 0x80, 0xb8, 0x73, 0x47, 0x3b, 0x33, 0xbb, 0xd9, 0xb5, + 0xd7, 0xb1, 0x1d, 0x0e, 0xdc, 0x76, 0x66, 0xde, 0x7b, 0xdf, 0xf7, 0xde, 0x9b, 0x79, 0xef, 0x2d, + 0x18, 0x9c, 0x5a, 0x2e, 0x15, 0xa6, 0xc5, 0xb6, 0xeb, 0x0d, 0x41, 0xcd, 0x27, 0xb9, 0x12, 0x15, + 0x24, 0x67, 0x3e, 0x6e, 0x50, 0xb7, 0x99, 0xad, 0xbb, 0x4c, 0x30, 0x3c, 0xa5, 0x64, 0xb2, 0x5a, + 0x26, 0xab, 0x65, 0xd2, 0x93, 0x15, 0x56, 0x61, 0x52, 0xc4, 0xf4, 0xbe, 0x94, 0x74, 0xba, 0x93, + 0x45, 0xd1, 0xac, 0x53, 0xae, 0x65, 0xa6, 0x2b, 0x8c, 0x55, 0x6a, 0xd4, 0x94, 0xab, 0x52, 0x63, + 0xcb, 0xa4, 0xdb, 0x75, 0xa1, 0xe1, 0xd2, 0x57, 0xf4, 0x21, 0xa9, 0xdb, 0x26, 0x71, 0x1c, 0x26, + 0x88, 0xb0, 0x99, 0xe3, 0xab, 0xbe, 0x60, 0x31, 0xbe, 0xcd, 0xb8, 0x59, 0x22, 0x9c, 0x9a, 0xa4, + 0x64, 0xd9, 0x01, 0x80, 0xb7, 0xd0, 0x42, 0x0b, 0x61, 0x21, 0xe9, 0x4a, 0x20, 0x55, 0x27, 0x15, + 0xdb, 0x91, 0x16, 0x95, 0xac, 0xf1, 0x3e, 0xa4, 0xdf, 0xf1, 0x24, 0x1e, 0x48, 0xda, 0x6b, 0xcc, + 0x11, 0x2e, 0xb1, 0x44, 0x81, 0x3e, 0x6e, 0x50, 0x2e, 0xf0, 0x3c, 0x4c, 0x58, 0x7a, 0xab, 0x48, + 0xca, 0x65, 0x97, 0x72, 0x9e, 0x42, 0x57, 0xd1, 0xdc, 0x70, 0x61, 0xdc, 0xdf, 0x5f, 0x51, 0xdb, + 0x78, 0x12, 0x06, 0x24, 0x54, 0xea, 0xcc, 0x55, 0x34, 0x37, 0x5a, 0x50, 0x0b, 0x63, 0x11, 0x9e, + 0x93, 0xe6, 0x57, 0x9b, 0x9b, 0xa4, 0x44, 0x6b, 0xbe, 0xdd, 0x49, 0x18, 0xa8, 0x79, 0x6b, 0x6d, + 0x4c, 0x2d, 0x8c, 0x37, 0xe0, 0x79, 0x2d, 0xbc, 0x16, 0x35, 0xde, 0x3f, 0x1d, 0xc3, 0x84, 0xc9, + 0xc0, 0x56, 0x99, 0x6e, 0x94, 0x7d, 0x13, 0x97, 0x60, 0xc8, 0x62, 0x65, 0x5a, 0xb4, 0xcb, 0x52, + 0x33, 0x59, 0x18, 0xb4, 0xe4, 0xb9, 0x91, 0x83, 0xe9, 0xd8, 0x40, 0xf0, 0x3a, 0x73, 0x38, 0xc5, + 0x18, 0x92, 0x65, 0x22, 0x88, 0x54, 0x1a, 0x2d, 0xc8, 0x6f, 0xe3, 0x2b, 0x04, 0x97, 0xa5, 0x8e, + 0x2f, 0xbd, 0xe1, 0x6c, 0xb1, 0x40, 0xa3, 0x8f, 0xd8, 0x15, 0x60, 0x34, 0x6c, 0x42, 0x86, 0x70, + 0x24, 0x7f, 0x3d, 0x1b, 0x7f, 0xf3, 0xb2, 0x61, 0xd9, 0xd5, 0x73, 0x07, 0xcf, 0x66, 0xd0, 0xdf, + 0xcf, 0x66, 0x12, 0x85, 0x88, 0x0d, 0xe3, 0x4b, 0x04, 0x97, 0xc2, 0x1b, 0xef, 0xda, 0xa2, 0xea, + 0xe3, 0xfd, 0xcf, 0xd4, 0x3e, 0x84, 0x4c, 0x24, 0x6c, 0xfc, 0x38, 0x49, 0x3a, 0x76, 0x0f, 0x61, + 0x2c, 0x20, 0x68, 0x3b, 0x5b, 0xcc, 0xa3, 0x77, 0x76, 0x6e, 0x24, 0x6f, 0xf6, 0x82, 0x1b, 0xf2, + 0x74, 0x35, 0xb9, 0xef, 0xc1, 0x9f, 0xb7, 0x42, 0xc7, 0xdc, 0xf8, 0x0c, 0xc1, 0x84, 0x04, 0x0c, + 0xa7, 0xab, 0xd3, 0xc5, 0xc0, 0x29, 0x18, 0xb2, 0x5c, 0x4a, 0x04, 0x73, 0xa5, 0xf3, 0xc3, 0x05, + 0x7f, 0x89, 0xa7, 0x61, 0x58, 0xaa, 0x54, 0x09, 0xaf, 0xa6, 0xce, 0xca, 0xb3, 0x73, 0xde, 0xc6, + 0x3d, 0xc2, 0xab, 0x78, 0x0a, 0x06, 0x39, 0x6b, 0xb8, 0x16, 0x4d, 0x25, 0xe5, 0x89, 0x5e, 0x79, + 0xe6, 0x4a, 0x0d, 0xbb, 0x56, 0xa6, 0x6e, 0x6a, 0x40, 0x99, 0xd3, 0x4b, 0x63, 0x17, 0x2e, 0xe8, + 0xb0, 0x94, 0x69, 0x40, 0xeb, 0x6d, 0x8d, 0xe1, 0x45, 0x41, 0x12, 0x1b, 0xc9, 0xcf, 0x75, 0x0e, + 0x42, 0xd4, 0xa7, 0x50, 0x02, 0x24, 0x2f, 0xef, 0xcc, 0xbb, 0xc8, 0x3b, 0x84, 0x6f, 0xeb, 0x67, + 0x2a, 0xbf, 0x0d, 0x0b, 0x70, 0x80, 0xcc, 0x03, 0xe8, 0x37, 0x01, 0x02, 0x68, 0x3f, 0x01, 0xbd, + 0x63, 0xab, 0xc8, 0x0f, 0xfb, 0xb8, 0xdc, 0xd8, 0x80, 0x2b, 0x91, 0xac, 0x07, 0x6f, 0xbb, 0xef, + 0xf7, 0x62, 0xe4, 0x75, 0xd1, 0xf2, 0x4d, 0xe9, 0xda, 0xa2, 0x0d, 0xc5, 0x17, 0x97, 0x65, 0xb8, + 0x18, 0xf8, 0xe8, 0x25, 0x28, 0x10, 0x8f, 0x64, 0x11, 0x45, 0xb3, 0x68, 0x7c, 0x8e, 0x60, 0xfc, + 0x2e, 0xb5, 0xdc, 0x66, 0x5d, 0xd0, 0xf2, 0x8a, 0xc3, 0x77, 0xa8, 0xeb, 0x45, 0xd0, 0xab, 0xe6, + 0x5a, 0x56, 0x7e, 0x7b, 0x98, 0xb6, 0x53, 0x6f, 0x08, 0x7d, 0x45, 0xd4, 0x02, 0xcf, 0xc0, 0x08, + 0x6b, 0x88, 0x7a, 0x43, 0x14, 0x65, 0xed, 0x50, 0x57, 0x04, 0xd4, 0xd6, 0x5d, 0x22, 0x08, 0xce, + 0xc1, 0xc5, 0x90, 0x40, 0x91, 0xf0, 0x22, 0x17, 0xae, 0xed, 0x54, 0xf4, 0x9d, 0xc1, 0xc7, 0xa2, + 0x2b, 0xfc, 0x81, 0x3c, 0xb9, 0x93, 0xfc, 0xeb, 0x9b, 0x99, 0x84, 0xf1, 0x0f, 0x82, 0x89, 0x16, + 0x5e, 0x1c, 0xaf, 0xc0, 0x10, 0x51, 0x9f, 0x3a, 0x5b, 0xb3, 0x9d, 0xb2, 0xd5, 0xa2, 0x5a, 0xf0, + 0xf5, 0xf0, 0x66, 0xc0, 0xb8, 0xc6, 0x2a, 0x3c, 0x75, 0x46, 0x9a, 0x79, 0x31, 0xab, 0x1a, 0x4a, + 0xd6, 0x6b, 0x28, 0x59, 0xd9, 0x68, 0x7c, 0x43, 0x8a, 0xd4, 0xfa, 0x13, 0xea, 0x08, 0x9d, 0x71, + 0xed, 0xde, 0x26, 0xab, 0x70, 0x7c, 0x0d, 0x46, 0xb5, 0x35, 0xea, 0xba, 0xcc, 0xd5, 0x01, 0xd0, + 0x08, 0xeb, 0xde, 0x16, 0x9e, 0x85, 0xf1, 0x7a, 0x8d, 0xd8, 0x8e, 0xa0, 0xbb, 0xbe, 0x94, 0xf2, + 0x7d, 0x2c, 0xd8, 0x96, 0x82, 0xda, 0xef, 0x2f, 0x90, 0x2e, 0xd3, 0x7e, 0xea, 0xef, 0xd9, 0x5c, + 0x30, 0xb7, 0x79, 0x8a, 0x86, 0xf5, 0x1a, 0xc0, 0x71, 0x37, 0xd4, 0x75, 0xed, 0x46, 0xc4, 0x53, + 0x35, 0x05, 0xf8, 0xae, 0xde, 0x27, 0x15, 0xaa, 0x61, 0x0a, 0x21, 0x4d, 0x4d, 0xec, 0x67, 0xd4, + 0x72, 0xbd, 0x03, 0x62, 0xfa, 0x9a, 0xdd, 0x87, 0x21, 0xea, 0x08, 0xd7, 0xa6, 0x7e, 0x72, 0x6e, + 0x75, 0xab, 0x65, 0xf2, 0xa6, 0x2a, 0x2b, 0xeb, 0x8e, 0x70, 0x9b, 0x3a, 0xc0, 0xbe, 0x19, 0xfc, + 0x7a, 0x8c, 0x03, 0xb3, 0x5d, 0x1d, 0x50, 0x74, 0xda, 0x3d, 0xc8, 0x7f, 0x7d, 0x1e, 0x06, 0xa4, + 0x07, 0xf8, 0x7b, 0x14, 0x2d, 0xfa, 0xf8, 0xe5, 0x4e, 0x54, 0x4f, 0x6c, 0xd7, 0xe9, 0xdc, 0x89, + 0x6a, 0x71, 0x4d, 0xd3, 0xb8, 0xf5, 0xd1, 0xaf, 0x7f, 0x7e, 0x7a, 0x66, 0x01, 0xcf, 0xb5, 0x0d, + 0x50, 0x5e, 0x15, 0x32, 0x3f, 0x68, 0x4d, 0xee, 0x1e, 0xfe, 0x0e, 0xc1, 0x85, 0xb6, 0x46, 0x82, + 0x6f, 0x76, 0x65, 0x1c, 0x1a, 0x0a, 0xd2, 0xb7, 0x7b, 0x22, 0xda, 0xd6, 0xa6, 0x8c, 0x9b, 0x92, + 0xed, 0x0d, 0x7c, 0xbd, 0x8d, 0xad, 0xcf, 0x93, 0x7b, 0x94, 0x65, 0x57, 0xd9, 0xc3, 0x3f, 0x22, + 0x3d, 0x0c, 0x45, 0x47, 0x0c, 0x9c, 0x3f, 0x11, 0x3d, 0x76, 0x30, 0x4b, 0x2f, 0xf5, 0xa5, 0xa3, + 0xe9, 0xe6, 0x24, 0xdd, 0x45, 0x3c, 0x1f, 0x3f, 0xef, 0xc6, 0x45, 0xf7, 0x63, 0x04, 0x49, 0xcf, + 0xe9, 0x3e, 0x03, 0x3a, 0xdf, 0x25, 0xa0, 0xc7, 0x0d, 0xce, 0x98, 0x95, 0xa4, 0xae, 0xe1, 0x99, + 0x98, 0x18, 0x96, 0x69, 0x28, 0x7c, 0x8f, 0x60, 0x40, 0xf6, 0x27, 0x3c, 0x95, 0x55, 0x23, 0x72, + 0xd6, 0x9f, 0x9f, 0xb3, 0xeb, 0xde, 0xfc, 0x9c, 0x5e, 0xe8, 0x0a, 0x1a, 0x34, 0x1b, 0x23, 0x23, + 0x51, 0x53, 0x78, 0x2a, 0x16, 0x95, 0xe3, 0x5f, 0x10, 0x5c, 0xf6, 0x3b, 0x45, 0xdb, 0xfd, 0x3e, + 0xed, 0x7b, 0x78, 0xa9, 0x2b, 0xc1, 0x70, 0x63, 0x32, 0x36, 0x24, 0xc7, 0x35, 0xbc, 0x12, 0xcb, + 0x51, 0xf6, 0x2b, 0xb3, 0xd4, 0x2c, 0xb6, 0x26, 0x2d, 0x2e, 0x8d, 0x4f, 0xf5, 0xc4, 0xe3, 0xbb, + 0x73, 0x8a, 0x37, 0xd2, 0x27, 0xf9, 0x57, 0x24, 0xf9, 0x1c, 0x36, 0xbb, 0x91, 0x97, 0xd9, 0x0d, + 0xa5, 0xf9, 0x07, 0x04, 0x63, 0xb2, 0x9f, 0xaf, 0x36, 0xff, 0x63, 0xb8, 0xf3, 0x3d, 0xbd, 0xea, + 0xc8, 0xec, 0x70, 0xc2, 0x13, 0x91, 0x53, 0x44, 0x5c, 0x6c, 0xbf, 0x45, 0x30, 0xe6, 0x8f, 0x9b, + 0xea, 0x2f, 0x07, 0x2f, 0x76, 0x21, 0x1c, 0xfe, 0x17, 0x4a, 0x2f, 0xf7, 0x44, 0xb3, 0x65, 0x5a, + 0x3a, 0x81, 0x68, 0xfb, 0x7d, 0x90, 0xd4, 0xf7, 0xf0, 0x4f, 0x08, 0xc6, 0x5b, 0xba, 0x13, 0x5e, + 0xea, 0x09, 0x3c, 0xda, 0x64, 0x7b, 0x64, 0xdc, 0xd2, 0x00, 0x8d, 0x57, 0x25, 0xe3, 0xdb, 0x78, + 0xb9, 0x33, 0xe3, 0xaa, 0x52, 0x89, 0x89, 0xf2, 0xea, 0xc3, 0xfd, 0x3f, 0x32, 0x89, 0xa7, 0x87, + 0x19, 0xb4, 0x7f, 0x98, 0x41, 0x07, 0x87, 0x19, 0xf4, 0xfb, 0x61, 0x06, 0x7d, 0x72, 0x94, 0x49, + 0x1c, 0x1c, 0x65, 0x12, 0xbf, 0x1d, 0x65, 0x12, 0xef, 0xdd, 0xa9, 0xd8, 0xa2, 0xda, 0x28, 0x79, + 0xa4, 0x4c, 0x6e, 0xb9, 0xa2, 0x46, 0x4a, 0xdc, 0x54, 0x95, 0xf0, 0x2d, 0x2a, 0x76, 0x98, 0xfb, + 0xc8, 0xdc, 0x0d, 0xa0, 0xbd, 0xc9, 0xc2, 0x75, 0x48, 0x4d, 0xfd, 0x97, 0x97, 0x06, 0x65, 0x29, + 0x59, 0xfa, 0x37, 0x00, 0x00, 0xff, 0xff, 0x95, 0x99, 0xf7, 0x6a, 0x10, 0x10, 0x00, 0x00, } func (this *QuerySecretContractRequest) Equal(that interface{}) bool { @@ -1210,65 +1210,6 @@ func (this *QueryCodeHashResponse) Equal(that interface{}) bool { } return true } -func (this *QueryContractHistoryRequest) Equal(that interface{}) bool { - if that == nil { - return this == nil - } - - that1, ok := that.(*QueryContractHistoryRequest) - if !ok { - that2, ok := that.(QueryContractHistoryRequest) - if ok { - that1 = &that2 - } else { - return false - } - } - if that1 == nil { - return this == nil - } else if this == nil { - return false - } - if this.ContractAddress != that1.ContractAddress { - return false - } - if !this.Pagination.Equal(that1.Pagination) { - return false - } - return true -} -func (this *QueryContractHistoryResponse) Equal(that interface{}) bool { - if that == nil { - return this == nil - } - - that1, ok := that.(*QueryContractHistoryResponse) - if !ok { - that2, ok := that.(QueryContractHistoryResponse) - if ok { - that1 = &that2 - } else { - return false - } - } - if that1 == nil { - return this == nil - } else if this == nil { - return false - } - if len(this.Entries) != len(that1.Entries) { - return false - } - for i := range this.Entries { - if !this.Entries[i].Equal(&that1.Entries[i]) { - return false - } - } - if !this.Pagination.Equal(that1.Pagination) { - return false - } - return true -} // Reference imports to suppress errors if they are not otherwise used. var _ context.Context diff --git a/x/compute/internal/types/types.go b/x/compute/internal/types/types.go index 3598936be..e156a9d45 100644 --- a/x/compute/internal/types/types.go +++ b/x/compute/internal/types/types.go @@ -1,7 +1,6 @@ package types import ( - "encoding/base64" fmt "fmt" "strings" @@ -21,9 +20,6 @@ const ( defaultQueryGasLimit = uint64(10_000_000) ) -// base64 of a 64 byte key -type ContractKey string - func (m Model) ValidateBasic() error { if len(m.Key) == 0 { return sdkerrors.Wrap(ErrEmpty, "key") @@ -123,7 +119,7 @@ func (a *AbsoluteTxPosition) Bytes() []byte { } // NewEnv initializes the environment for a contract instance -func NewEnv(ctx sdk.Context, creator sdk.AccAddress, deposit sdk.Coins, contractAddr sdk.AccAddress, contractKey []byte, random []byte) wasmTypes.Env { +func NewEnv(ctx sdk.Context, creator sdk.AccAddress, deposit sdk.Coins, contractAddr sdk.AccAddress, contractKey *ContractKey, random []byte) wasmTypes.Env { // safety checks before casting below if ctx.BlockHeight() < 0 { panic("Block height must never be negative") @@ -146,10 +142,19 @@ func NewEnv(ctx sdk.Context, creator sdk.AccAddress, deposit sdk.Coins, contract Contract: wasmTypes.ContractInfo{ Address: contractAddr.String(), }, - Key: wasmTypes.ContractKey(base64.StdEncoding.EncodeToString(contractKey)), QueryDepth: 1, } + if contractKey != nil { + env.Key = &wasmTypes.ContractKey{ + Key: contractKey.Key, + Original: wasmTypes.ContractKeyWithProof{ + Proof: contractKey.Original.Proof, + Key: contractKey.Original.Proof, + }, + } + } + if txCounter, ok := TXCounter(ctx); ok { env.Transaction = &wasmTypes.TransactionInfo{Index: txCounter} } diff --git a/x/compute/internal/types/types.pb.go b/x/compute/internal/types/types.pb.go index 150c4bd8b..1f522fa20 100644 --- a/x/compute/internal/types/types.pb.go +++ b/x/compute/internal/types/types.pb.go @@ -205,6 +205,82 @@ func (m *ContractCustomInfo) XXX_DiscardUnknown() { var xxx_messageInfo_ContractCustomInfo proto.InternalMessageInfo +type ContractKey struct { + Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Original *ContractKeyWithProof `protobuf:"bytes,2,opt,name=original,proto3" json:"original,omitempty"` +} + +func (m *ContractKey) Reset() { *m = ContractKey{} } +func (m *ContractKey) String() string { return proto.CompactTextString(m) } +func (*ContractKey) ProtoMessage() {} +func (*ContractKey) Descriptor() ([]byte, []int) { + return fileDescriptor_8ba7f40a6d1951b3, []int{3} +} +func (m *ContractKey) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ContractKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ContractKey.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ContractKey) XXX_Merge(src proto.Message) { + xxx_messageInfo_ContractKey.Merge(m, src) +} +func (m *ContractKey) XXX_Size() int { + return m.Size() +} +func (m *ContractKey) XXX_DiscardUnknown() { + xxx_messageInfo_ContractKey.DiscardUnknown(m) +} + +var xxx_messageInfo_ContractKey proto.InternalMessageInfo + +type ContractKeyWithProof struct { + Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Proof []byte `protobuf:"bytes,2,opt,name=proof,proto3" json:"proof,omitempty"` +} + +func (m *ContractKeyWithProof) Reset() { *m = ContractKeyWithProof{} } +func (m *ContractKeyWithProof) String() string { return proto.CompactTextString(m) } +func (*ContractKeyWithProof) ProtoMessage() {} +func (*ContractKeyWithProof) Descriptor() ([]byte, []int) { + return fileDescriptor_8ba7f40a6d1951b3, []int{4} +} +func (m *ContractKeyWithProof) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ContractKeyWithProof) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ContractKeyWithProof.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ContractKeyWithProof) XXX_Merge(src proto.Message) { + xxx_messageInfo_ContractKeyWithProof.Merge(m, src) +} +func (m *ContractKeyWithProof) XXX_Size() int { + return m.Size() +} +func (m *ContractKeyWithProof) XXX_DiscardUnknown() { + xxx_messageInfo_ContractKeyWithProof.DiscardUnknown(m) +} + +var xxx_messageInfo_ContractKeyWithProof proto.InternalMessageInfo + // ContractInfo stores a WASM contract instance type ContractInfo struct { // CodeID is the reference to the stored Wasm code @@ -218,13 +294,15 @@ type ContractInfo struct { IBCPortID string `protobuf:"bytes,6,opt,name=ibc_port_id,json=ibcPortId,proto3" json:"ibc_port_id,omitempty"` // Admin is an optional address that can execute migrations Admin github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,7,opt,name=admin,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"admin,omitempty"` + // Proof that enclave executed the instantiate command + AdminProof []byte `protobuf:"bytes,8,opt,name=admin_proof,json=adminProof,proto3" json:"admin_proof,omitempty"` } func (m *ContractInfo) Reset() { *m = ContractInfo{} } func (m *ContractInfo) String() string { return proto.CompactTextString(m) } func (*ContractInfo) ProtoMessage() {} func (*ContractInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_8ba7f40a6d1951b3, []int{3} + return fileDescriptor_8ba7f40a6d1951b3, []int{5} } func (m *ContractInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -265,7 +343,7 @@ func (m *AbsoluteTxPosition) Reset() { *m = AbsoluteTxPosition{} } func (m *AbsoluteTxPosition) String() string { return proto.CompactTextString(m) } func (*AbsoluteTxPosition) ProtoMessage() {} func (*AbsoluteTxPosition) Descriptor() ([]byte, []int) { - return fileDescriptor_8ba7f40a6d1951b3, []int{4} + return fileDescriptor_8ba7f40a6d1951b3, []int{6} } func (m *AbsoluteTxPosition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -306,7 +384,7 @@ func (m *Model) Reset() { *m = Model{} } func (m *Model) String() string { return proto.CompactTextString(m) } func (*Model) ProtoMessage() {} func (*Model) Descriptor() ([]byte, []int) { - return fileDescriptor_8ba7f40a6d1951b3, []int{5} + return fileDescriptor_8ba7f40a6d1951b3, []int{7} } func (m *Model) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -349,7 +427,7 @@ func (m *ContractCodeHistoryEntry) Reset() { *m = ContractCodeHistoryEnt func (m *ContractCodeHistoryEntry) String() string { return proto.CompactTextString(m) } func (*ContractCodeHistoryEntry) ProtoMessage() {} func (*ContractCodeHistoryEntry) Descriptor() ([]byte, []int) { - return fileDescriptor_8ba7f40a6d1951b3, []int{6} + return fileDescriptor_8ba7f40a6d1951b3, []int{8} } func (m *ContractCodeHistoryEntry) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -384,6 +462,8 @@ func init() { proto.RegisterType((*AccessTypeParam)(nil), "secret.compute.v1beta1.AccessTypeParam") proto.RegisterType((*CodeInfo)(nil), "secret.compute.v1beta1.CodeInfo") proto.RegisterType((*ContractCustomInfo)(nil), "secret.compute.v1beta1.ContractCustomInfo") + proto.RegisterType((*ContractKey)(nil), "secret.compute.v1beta1.ContractKey") + proto.RegisterType((*ContractKeyWithProof)(nil), "secret.compute.v1beta1.ContractKeyWithProof") proto.RegisterType((*ContractInfo)(nil), "secret.compute.v1beta1.ContractInfo") proto.RegisterType((*AbsoluteTxPosition)(nil), "secret.compute.v1beta1.AbsoluteTxPosition") proto.RegisterType((*Model)(nil), "secret.compute.v1beta1.Model") @@ -395,68 +475,73 @@ func init() { } var fileDescriptor_8ba7f40a6d1951b3 = []byte{ - // 974 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0xcd, 0x6e, 0x23, 0x45, - 0x10, 0xf6, 0xc4, 0x8e, 0x1d, 0x77, 0xcc, 0x62, 0x35, 0x61, 0xf1, 0x1a, 0xc9, 0x1e, 0x06, 0x04, - 0x21, 0x21, 0x36, 0x59, 0x38, 0xac, 0x72, 0xf3, 0xcf, 0x6c, 0x32, 0x1b, 0x32, 0xb6, 0xda, 0x4e, - 0x50, 0xf8, 0xd1, 0x68, 0x7e, 0x2a, 0xf6, 0x28, 0xe3, 0x69, 0x6b, 0xba, 0x1d, 0x3c, 0x6f, 0x80, - 0x7c, 0xe2, 0xc8, 0xc5, 0x12, 0x12, 0x68, 0xb5, 0x2f, 0xc0, 0x3b, 0xec, 0x71, 0x0f, 0x1c, 0x38, - 0x59, 0xe0, 0x3c, 0x00, 0x12, 0xc7, 0x3d, 0xa1, 0x69, 0x3b, 0xb1, 0x05, 0x1b, 0x25, 0x20, 0x4e, - 0x53, 0xd5, 0x5d, 0xf5, 0xd5, 0xdf, 0x57, 0xd3, 0x48, 0x61, 0x60, 0x07, 0xc0, 0xcb, 0x36, 0xed, - 0xf5, 0x07, 0x1c, 0xca, 0x17, 0xbb, 0x16, 0x70, 0x73, 0xb7, 0xcc, 0xc3, 0x3e, 0xb0, 0x52, 0x3f, - 0xa0, 0x9c, 0xe2, 0xfb, 0x33, 0x9b, 0xd2, 0xdc, 0xa6, 0x34, 0xb7, 0xc9, 0x6f, 0x74, 0x68, 0x87, - 0x0a, 0x93, 0x72, 0x24, 0xcd, 0xac, 0x15, 0x1b, 0xbd, 0x5e, 0xb1, 0x6d, 0x60, 0xac, 0x1d, 0xf6, - 0xa1, 0x69, 0x06, 0x66, 0x0f, 0x3f, 0x41, 0xab, 0x17, 0xa6, 0x37, 0x80, 0x9c, 0x24, 0x4b, 0x9b, - 0xf7, 0x1e, 0x2a, 0xa5, 0x57, 0x03, 0x96, 0x16, 0x7e, 0xd5, 0xec, 0x9f, 0x93, 0x62, 0x26, 0x34, - 0x7b, 0xde, 0x9e, 0x22, 0x5c, 0x15, 0x32, 0x83, 0xd8, 0x4b, 0x7c, 0xff, 0x43, 0x51, 0x52, 0x9e, - 0x4a, 0x68, 0xad, 0x46, 0x1d, 0xd0, 0xfc, 0x33, 0x8a, 0xdf, 0x46, 0x69, 0x9b, 0x3a, 0x60, 0x74, - 0x4d, 0xd6, 0x15, 0x21, 0x32, 0x64, 0x2d, 0x3a, 0x38, 0x30, 0x59, 0x17, 0x1f, 0xa2, 0x94, 0x1d, - 0x80, 0xc9, 0x69, 0x90, 0x5b, 0x89, 0xae, 0xaa, 0xbb, 0x2f, 0x27, 0xc5, 0x9d, 0x8e, 0xcb, 0xbb, - 0x03, 0x2b, 0x4a, 0xa0, 0x6c, 0x53, 0xd6, 0xa3, 0x6c, 0xfe, 0xd9, 0x61, 0xce, 0xf9, 0xbc, 0xf6, - 0x8a, 0x6d, 0x57, 0x1c, 0x27, 0x00, 0xc6, 0xc8, 0x15, 0x02, 0xbe, 0x8f, 0x92, 0x8c, 0x0e, 0x02, - 0x1b, 0x72, 0x71, 0x59, 0xda, 0x4c, 0x93, 0xb9, 0x86, 0x73, 0x28, 0x65, 0x0d, 0x5c, 0xcf, 0x81, - 0x20, 0x97, 0x10, 0x17, 0x57, 0xaa, 0xf2, 0x25, 0xc2, 0x35, 0xea, 0xf3, 0xc0, 0xb4, 0x79, 0x6d, - 0xc0, 0x38, 0xed, 0x89, 0x8c, 0xcb, 0x68, 0x1d, 0x7c, 0xdb, 0x33, 0x2f, 0xc0, 0x38, 0x87, 0x70, - 0x96, 0x73, 0xf5, 0xde, 0x74, 0x52, 0x44, 0xea, 0xec, 0xf8, 0x10, 0x42, 0x82, 0xe0, 0x5a, 0xc6, - 0x1b, 0x68, 0xd5, 0x33, 0x2d, 0xf0, 0x44, 0x0d, 0x69, 0x32, 0x53, 0x94, 0x5f, 0x56, 0x50, 0xe6, - 0x0a, 0x5d, 0xe0, 0xbe, 0x8b, 0x52, 0xa2, 0x13, 0xae, 0x23, 0x30, 0x13, 0x55, 0x34, 0x9d, 0x14, - 0x93, 0xa2, 0x51, 0x75, 0x92, 0x8c, 0xae, 0x34, 0xe7, 0xff, 0xed, 0xc8, 0x75, 0x62, 0x89, 0xa5, - 0xc4, 0x70, 0x7d, 0x1e, 0x02, 0x9c, 0xdc, 0xaa, 0x2c, 0x6d, 0xae, 0x3f, 0xdc, 0xba, 0x71, 0xe4, - 0x16, 0xa3, 0xde, 0x80, 0x43, 0x7b, 0xd8, 0xa4, 0xcc, 0xe5, 0x2e, 0xf5, 0xc9, 0x95, 0x2b, 0xde, - 0x41, 0xeb, 0xae, 0x65, 0x1b, 0x7d, 0x1a, 0xf0, 0xa8, 0xa2, 0x64, 0x14, 0xa1, 0xfa, 0xda, 0x74, - 0x52, 0x4c, 0x6b, 0xd5, 0x5a, 0x93, 0x06, 0x5c, 0xab, 0x93, 0xb4, 0x6b, 0xd9, 0x42, 0x74, 0xf0, - 0x3e, 0x5a, 0x35, 0x9d, 0x9e, 0xeb, 0xe7, 0x52, 0xff, 0xb5, 0xaa, 0x99, 0xbf, 0x42, 0x10, 0xfe, - 0x67, 0x5a, 0xf8, 0x1d, 0x94, 0xb1, 0x3c, 0x6a, 0x9f, 0x1b, 0x5d, 0x70, 0x3b, 0x5d, 0x2e, 0x1a, - 0x1c, 0x27, 0xeb, 0xe2, 0xec, 0x40, 0x1c, 0xe1, 0x07, 0x68, 0x8d, 0x0f, 0x0d, 0xd7, 0x77, 0x60, - 0x28, 0x5a, 0x9b, 0x20, 0x29, 0x3e, 0xd4, 0x22, 0x55, 0x71, 0xd1, 0xea, 0x11, 0x75, 0xc0, 0xc3, - 0x4f, 0x50, 0xfc, 0xf0, 0x7a, 0xe4, 0x8f, 0x5e, 0x4e, 0x8a, 0x9f, 0x2e, 0xe5, 0xc8, 0xc1, 0x77, - 0x20, 0xe8, 0xb9, 0x3e, 0x5f, 0x16, 0x3d, 0xd7, 0x62, 0x65, 0x2b, 0xe4, 0xc0, 0x4a, 0x07, 0x30, - 0xac, 0x46, 0x02, 0x89, 0xcf, 0x59, 0x71, 0x22, 0xf6, 0x4a, 0xcc, 0x91, 0xcc, 0x14, 0xe5, 0x0f, - 0x09, 0xe5, 0xae, 0x39, 0x17, 0xad, 0x81, 0xcb, 0x38, 0x0d, 0x42, 0xd5, 0xe7, 0x41, 0x88, 0x4f, - 0x50, 0x9a, 0xf6, 0x21, 0x30, 0xa3, 0x92, 0xe6, 0xeb, 0xf8, 0xe8, 0xa6, 0xd9, 0xbc, 0x02, 0xa4, - 0x71, 0xe5, 0x1b, 0x2d, 0x29, 0x59, 0x40, 0x2d, 0x33, 0x6f, 0xe5, 0x46, 0xe6, 0xd5, 0x51, 0x6a, - 0xd0, 0x77, 0x04, 0x2d, 0xe2, 0xff, 0x9e, 0x16, 0x73, 0x57, 0x9c, 0x45, 0xf1, 0x1e, 0xeb, 0x08, - 0xc2, 0x65, 0x48, 0x24, 0x6e, 0xfd, 0x2c, 0x21, 0xb4, 0xf8, 0x77, 0xe0, 0xf7, 0x51, 0xfa, 0x58, - 0xaf, 0xab, 0x8f, 0x35, 0x5d, 0xad, 0x67, 0x63, 0xf9, 0xb7, 0x46, 0x63, 0xf9, 0x8d, 0xc5, 0xf5, - 0xb1, 0xef, 0xc0, 0x99, 0xeb, 0x83, 0x83, 0x65, 0x94, 0xd4, 0x1b, 0xd5, 0x46, 0xfd, 0x34, 0x2b, - 0xe5, 0x37, 0x46, 0x63, 0x39, 0xbb, 0x30, 0xd2, 0xa9, 0x45, 0x9d, 0x10, 0x6f, 0xa3, 0x4c, 0x43, - 0xff, 0xec, 0xd4, 0xa8, 0xd4, 0xeb, 0x44, 0x6d, 0xb5, 0xb2, 0x2b, 0xf9, 0x07, 0xa3, 0xb1, 0xfc, - 0xe6, 0xc2, 0xae, 0xe1, 0x7b, 0xe1, 0x9c, 0x3d, 0x51, 0x58, 0xf5, 0x44, 0x25, 0xa7, 0x02, 0x31, - 0xfe, 0xf7, 0xb0, 0xea, 0x05, 0x04, 0x61, 0x04, 0x9a, 0x5f, 0xfb, 0xf6, 0xc7, 0x42, 0xec, 0xd9, - 0x4f, 0x85, 0xd8, 0xd6, 0xd3, 0x38, 0x92, 0x6f, 0x6b, 0x32, 0x06, 0xf4, 0x71, 0xad, 0xa1, 0xb7, - 0x49, 0xa5, 0xd6, 0x36, 0x6a, 0x8d, 0xba, 0x6a, 0x1c, 0x68, 0xad, 0x76, 0x83, 0x9c, 0x1a, 0x8d, - 0xa6, 0x4a, 0x2a, 0x6d, 0xad, 0xa1, 0x1b, 0xed, 0xd3, 0xa6, 0x6a, 0x1c, 0xeb, 0xad, 0xa6, 0x5a, - 0xd3, 0x1e, 0x6b, 0xa2, 0xe8, 0xf2, 0x68, 0x2c, 0x6f, 0xdf, 0x86, 0x7d, 0xec, 0xb3, 0x3e, 0xd8, - 0xee, 0x99, 0x0b, 0x0e, 0xfe, 0x1c, 0x7d, 0x78, 0xa7, 0x30, 0x9a, 0xae, 0xb5, 0xb3, 0x52, 0x7e, - 0x73, 0x34, 0x96, 0xdf, 0xbb, 0x0d, 0x5f, 0xf3, 0x5d, 0x8e, 0xbf, 0x46, 0x1f, 0xdd, 0x09, 0xf8, - 0x48, 0xdb, 0x27, 0x95, 0xb6, 0x9a, 0x5d, 0xc9, 0x6f, 0x8f, 0xc6, 0xf2, 0x07, 0xb7, 0x61, 0x1f, - 0xb9, 0x9d, 0xc0, 0xe4, 0x70, 0x67, 0xf8, 0x7d, 0x55, 0x57, 0x5b, 0x5a, 0x2b, 0x1b, 0xbf, 0x1b, - 0xfc, 0x3e, 0xf8, 0xc0, 0x5c, 0x96, 0x4f, 0x44, 0xc3, 0xaa, 0x7e, 0xf5, 0xfc, 0xf7, 0x42, 0xec, - 0xd9, 0xb4, 0x20, 0x3d, 0x9f, 0x16, 0xa4, 0x17, 0xd3, 0x82, 0xf4, 0xdb, 0xb4, 0x20, 0x7d, 0x77, - 0x59, 0x88, 0xbd, 0xb8, 0x2c, 0xc4, 0x7e, 0xbd, 0x2c, 0xc4, 0xbe, 0xd8, 0x5b, 0xda, 0x62, 0x66, - 0x07, 0xdc, 0x33, 0x2d, 0x56, 0x6e, 0x09, 0x72, 0xeb, 0xc0, 0xbf, 0xa1, 0xc1, 0x79, 0x79, 0x78, - 0xfd, 0xc8, 0xba, 0x3e, 0x87, 0xc0, 0x37, 0xbd, 0xd9, 0x1f, 0xc8, 0x4a, 0x8a, 0x87, 0xf3, 0x93, - 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0xe8, 0xb4, 0x45, 0xcb, 0x8c, 0x07, 0x00, 0x00, + // 1047 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xcb, 0x6e, 0x23, 0x45, + 0x17, 0x76, 0xc7, 0xf7, 0xb2, 0xff, 0xf9, 0xad, 0x22, 0x0c, 0x1e, 0x23, 0xd9, 0xa6, 0x41, 0x10, + 0x92, 0x89, 0x4d, 0x06, 0x16, 0xa3, 0x2c, 0x90, 0x7c, 0xe9, 0x49, 0x7a, 0x42, 0x6c, 0xab, 0xec, + 0x64, 0x14, 0x2e, 0x6a, 0xf5, 0xa5, 0x62, 0x97, 0xd2, 0xee, 0xb2, 0xba, 0xca, 0xc1, 0x7e, 0x03, + 0xe4, 0x15, 0x4b, 0x36, 0x96, 0x90, 0x40, 0xa3, 0x79, 0x01, 0xde, 0x61, 0x96, 0xb3, 0x64, 0x65, + 0x81, 0xf3, 0x00, 0x48, 0x48, 0x6c, 0x66, 0x85, 0xba, 0xba, 0x7d, 0x11, 0x24, 0x4a, 0x40, 0xac, + 0xfa, 0x9c, 0xaa, 0x73, 0xbe, 0x53, 0xe7, 0x3b, 0x5f, 0x95, 0x1a, 0xc8, 0x0c, 0x9b, 0x2e, 0xe6, + 0x65, 0x93, 0xf6, 0x07, 0x43, 0x8e, 0xcb, 0x97, 0x7b, 0x06, 0xe6, 0xfa, 0x5e, 0x99, 0x8f, 0x07, + 0x98, 0x95, 0x06, 0x2e, 0xe5, 0x14, 0xde, 0xf7, 0x63, 0x4a, 0x41, 0x4c, 0x29, 0x88, 0xc9, 0x6d, + 0x76, 0x69, 0x97, 0x8a, 0x90, 0xb2, 0x67, 0xf9, 0xd1, 0xb2, 0x09, 0xfe, 0x5f, 0x31, 0x4d, 0xcc, + 0x58, 0x67, 0x3c, 0xc0, 0x2d, 0xdd, 0xd5, 0xfb, 0xf0, 0x29, 0x88, 0x5e, 0xea, 0xf6, 0x10, 0x67, + 0xa5, 0xa2, 0xb4, 0x75, 0xef, 0x91, 0x5c, 0xba, 0x1e, 0xb0, 0xb4, 0xca, 0xab, 0x66, 0x7e, 0x9f, + 0x15, 0xd2, 0x63, 0xbd, 0x6f, 0xef, 0xcb, 0x22, 0x55, 0x46, 0x3e, 0xc4, 0x7e, 0xe4, 0xbb, 0xef, + 0x0b, 0x92, 0xfc, 0x5c, 0x02, 0x89, 0x1a, 0xb5, 0xb0, 0xea, 0x9c, 0x53, 0xf8, 0x36, 0x48, 0x9a, + 0xd4, 0xc2, 0x5a, 0x4f, 0x67, 0x3d, 0x51, 0x22, 0x8d, 0x12, 0xde, 0xc2, 0xa1, 0xce, 0x7a, 0xf0, + 0x08, 0xc4, 0x4d, 0x17, 0xeb, 0x9c, 0xba, 0xd9, 0x0d, 0x6f, 0xab, 0xba, 0xf7, 0x7a, 0x56, 0xd8, + 0xed, 0x12, 0xde, 0x1b, 0x1a, 0xde, 0x01, 0xca, 0x26, 0x65, 0x7d, 0xca, 0x82, 0xcf, 0x2e, 0xb3, + 0x2e, 0x82, 0xde, 0x2b, 0xa6, 0x59, 0xb1, 0x2c, 0x17, 0x33, 0x86, 0x16, 0x08, 0xf0, 0x3e, 0x88, + 0x31, 0x3a, 0x74, 0x4d, 0x9c, 0x0d, 0x17, 0xa5, 0xad, 0x24, 0x0a, 0x3c, 0x98, 0x05, 0x71, 0x63, + 0x48, 0x6c, 0x0b, 0xbb, 0xd9, 0x88, 0xd8, 0x58, 0xb8, 0xf2, 0x17, 0x00, 0xd6, 0xa8, 0xc3, 0x5d, + 0xdd, 0xe4, 0xb5, 0x21, 0xe3, 0xb4, 0x2f, 0x4e, 0x5c, 0x06, 0x29, 0xec, 0x98, 0xb6, 0x7e, 0x89, + 0xb5, 0x0b, 0x3c, 0xf6, 0xcf, 0x5c, 0xbd, 0x37, 0x9f, 0x15, 0x80, 0xe2, 0x2f, 0x1f, 0xe1, 0x31, + 0x02, 0x78, 0x69, 0xc3, 0x4d, 0x10, 0xb5, 0x75, 0x03, 0xdb, 0xa2, 0x87, 0x24, 0xf2, 0x1d, 0x99, + 0x80, 0xd4, 0x02, 0xdc, 0x0b, 0xca, 0x80, 0xf0, 0x12, 0x0d, 0x79, 0x26, 0x3c, 0x04, 0x09, 0xea, + 0x92, 0x2e, 0x71, 0x74, 0x3f, 0x33, 0xf5, 0xe8, 0xe1, 0x4d, 0xdc, 0xaf, 0x01, 0x3d, 0x23, 0xbc, + 0xd7, 0x72, 0x29, 0x3d, 0x47, 0xcb, 0x6c, 0xf9, 0x53, 0xb0, 0x79, 0x5d, 0xc4, 0x35, 0x35, 0x37, + 0x41, 0x74, 0xe0, 0x6d, 0xf9, 0x74, 0x23, 0xdf, 0x91, 0xff, 0xd8, 0x00, 0xe9, 0x05, 0x80, 0xa0, + 0xe0, 0x5d, 0x10, 0x17, 0x43, 0x23, 0x96, 0x48, 0x8e, 0x54, 0xc1, 0x7c, 0x56, 0x88, 0x89, 0x99, + 0xd6, 0x51, 0xcc, 0xdb, 0x52, 0xad, 0xff, 0x76, 0x78, 0x4b, 0x0e, 0x23, 0x6b, 0x1c, 0xc2, 0x7a, + 0x50, 0x02, 0x5b, 0xd9, 0xa8, 0x60, 0x68, 0xfb, 0x46, 0x75, 0x1a, 0x8c, 0xda, 0x43, 0x8e, 0x3b, + 0xa3, 0x16, 0x65, 0x84, 0x13, 0xea, 0xa0, 0x45, 0x2a, 0xdc, 0x05, 0x29, 0x62, 0x98, 0xda, 0x80, + 0xba, 0xdc, 0xeb, 0x28, 0xe6, 0x55, 0xa8, 0xfe, 0x6f, 0x3e, 0x2b, 0x24, 0xd5, 0x6a, 0xad, 0x45, + 0x5d, 0xae, 0xd6, 0x51, 0x92, 0x18, 0xa6, 0x30, 0x2d, 0x78, 0x00, 0xa2, 0xba, 0xd5, 0x27, 0x4e, + 0x36, 0xfe, 0x6f, 0xbb, 0xf2, 0xf3, 0x61, 0x01, 0xa4, 0x84, 0xa1, 0xf9, 0x94, 0x27, 0x04, 0xe5, + 0x40, 0x2c, 0x89, 0xf9, 0xc8, 0x08, 0xc0, 0xbf, 0x9f, 0x1b, 0xbe, 0x03, 0xd2, 0x86, 0x4d, 0xcd, + 0x0b, 0xad, 0x87, 0x49, 0xb7, 0xc7, 0xc5, 0x04, 0xc2, 0x28, 0x25, 0xd6, 0x0e, 0xc5, 0x12, 0x7c, + 0x00, 0x12, 0x7c, 0xa4, 0x11, 0xc7, 0xc2, 0x23, 0xc1, 0x7d, 0x04, 0xc5, 0xf9, 0x48, 0xf5, 0x5c, + 0x99, 0x80, 0xe8, 0x31, 0xb5, 0xb0, 0x0d, 0x9f, 0x82, 0xf0, 0xd1, 0x52, 0xbe, 0x8f, 0x5f, 0xcf, + 0x0a, 0x9f, 0xac, 0x35, 0xc1, 0xb1, 0x63, 0x61, 0xb7, 0x4f, 0x1c, 0xbe, 0x6e, 0xda, 0xc4, 0x60, + 0x65, 0x63, 0xcc, 0x31, 0x2b, 0x1d, 0xe2, 0x51, 0xd5, 0x33, 0x50, 0x38, 0x50, 0xf8, 0xa9, 0x78, + 0x23, 0x02, 0xd9, 0x08, 0x47, 0xfe, 0x4d, 0x02, 0xd9, 0xe5, 0xfd, 0xf1, 0xae, 0x34, 0x61, 0x9c, + 0xba, 0x63, 0xc5, 0xe1, 0xee, 0x18, 0x9e, 0x82, 0x24, 0x1d, 0x60, 0x57, 0xf7, 0x5a, 0x0a, 0x9e, + 0x96, 0xc7, 0xb7, 0xc9, 0x7b, 0x0d, 0xa4, 0xb9, 0xc8, 0xf5, 0x1e, 0x1c, 0xb4, 0x82, 0x5a, 0x97, + 0xe6, 0xc6, 0x8d, 0xd2, 0xac, 0x83, 0xf8, 0x70, 0x60, 0x09, 0xdd, 0x84, 0xff, 0xb9, 0x6e, 0x82, + 0x54, 0xef, 0xfa, 0xf4, 0x59, 0x57, 0x28, 0x32, 0x8d, 0x3c, 0x73, 0xfb, 0x27, 0x09, 0x80, 0xd5, + 0x3b, 0x08, 0xdf, 0x07, 0xc9, 0x93, 0x46, 0x5d, 0x79, 0xa2, 0x36, 0x94, 0x7a, 0x26, 0x94, 0x7b, + 0x6b, 0x32, 0x2d, 0xbe, 0xb1, 0xda, 0x3e, 0x71, 0x2c, 0x7c, 0x4e, 0x1c, 0x6c, 0xc1, 0x22, 0x88, + 0x35, 0x9a, 0xd5, 0x66, 0xfd, 0x2c, 0x23, 0xe5, 0x36, 0x27, 0xd3, 0x62, 0x66, 0x15, 0xd4, 0xa0, + 0x06, 0xb5, 0xc6, 0x70, 0x07, 0xa4, 0x9b, 0x8d, 0xcf, 0xce, 0xb4, 0x4a, 0xbd, 0x8e, 0x94, 0x76, + 0x3b, 0xb3, 0x91, 0x7b, 0x30, 0x99, 0x16, 0xdf, 0x5c, 0xc5, 0x35, 0x1d, 0x7b, 0x1c, 0xc8, 0xcb, + 0x2b, 0xab, 0x9c, 0x2a, 0xe8, 0x4c, 0x20, 0x86, 0xff, 0x5a, 0x56, 0xb9, 0xc4, 0xee, 0xd8, 0x03, + 0xcd, 0x25, 0xbe, 0xf9, 0x21, 0x1f, 0x7a, 0xf1, 0x63, 0x3e, 0xb4, 0xfd, 0x3c, 0x0c, 0x8a, 0xb7, + 0x91, 0x0c, 0x31, 0xf8, 0xa8, 0xd6, 0x6c, 0x74, 0x50, 0xa5, 0xd6, 0xd1, 0x6a, 0xcd, 0xba, 0xa2, + 0x1d, 0xaa, 0xed, 0x4e, 0x13, 0x9d, 0x69, 0xcd, 0x96, 0x82, 0x2a, 0x1d, 0xb5, 0xd9, 0xd0, 0x3a, + 0x67, 0x2d, 0x45, 0x3b, 0x69, 0xb4, 0x5b, 0x4a, 0x4d, 0x7d, 0xa2, 0x8a, 0xa6, 0xcb, 0x93, 0x69, + 0x71, 0xe7, 0x36, 0xec, 0x13, 0x87, 0x0d, 0xb0, 0x49, 0xce, 0x09, 0xb6, 0xe0, 0x33, 0xf0, 0xe1, + 0x9d, 0xca, 0xa8, 0x0d, 0xb5, 0x93, 0x91, 0x72, 0x5b, 0x93, 0x69, 0xf1, 0xbd, 0xdb, 0xf0, 0x55, + 0x87, 0x70, 0xf8, 0x15, 0x78, 0x78, 0x27, 0xe0, 0x63, 0xf5, 0x00, 0x55, 0x3a, 0x4a, 0x66, 0x23, + 0xb7, 0x33, 0x99, 0x16, 0x3f, 0xb8, 0x0d, 0xfb, 0x98, 0x74, 0x5d, 0x9d, 0xe3, 0x3b, 0xc3, 0x1f, + 0x28, 0x0d, 0xa5, 0xad, 0xb6, 0x33, 0xe1, 0xbb, 0xc1, 0x1f, 0x60, 0x07, 0x33, 0xc2, 0x72, 0x11, + 0x6f, 0x58, 0xd5, 0x2f, 0x5f, 0xfe, 0x9a, 0x0f, 0xbd, 0x98, 0xe7, 0xa5, 0x97, 0xf3, 0xbc, 0xf4, + 0x6a, 0x9e, 0x97, 0x7e, 0x99, 0xe7, 0xa5, 0x6f, 0xaf, 0xf2, 0xa1, 0x57, 0x57, 0xf9, 0xd0, 0xcf, + 0x57, 0xf9, 0xd0, 0xe7, 0xfb, 0x6b, 0xb7, 0x98, 0x99, 0x2e, 0xb7, 0x75, 0x83, 0x95, 0xdb, 0x42, + 0xdc, 0x0d, 0xcc, 0xbf, 0xa6, 0xee, 0x45, 0x79, 0xb4, 0xfc, 0x61, 0x20, 0x0e, 0xc7, 0xae, 0xa3, + 0xdb, 0xfe, 0x13, 0x65, 0xc4, 0xc4, 0x4f, 0xc0, 0xc7, 0x7f, 0x06, 0x00, 0x00, 0xff, 0xff, 0x7b, + 0x22, 0x8a, 0xe1, 0x58, 0x08, 0x00, 0x00, } func (this *AccessTypeParam) Equal(that interface{}) bool { @@ -543,6 +628,60 @@ func (this *ContractCustomInfo) Equal(that interface{}) bool { } return true } +func (this *ContractKey) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*ContractKey) + if !ok { + that2, ok := that.(ContractKey) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if !bytes.Equal(this.Key, that1.Key) { + return false + } + if !this.Original.Equal(that1.Original) { + return false + } + return true +} +func (this *ContractKeyWithProof) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*ContractKeyWithProof) + if !ok { + that2, ok := that.(ContractKeyWithProof) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if !bytes.Equal(this.Key, that1.Key) { + return false + } + if !bytes.Equal(this.Proof, that1.Proof) { + return false + } + return true +} func (this *ContractInfo) Equal(that interface{}) bool { if that == nil { return this == nil @@ -580,6 +719,9 @@ func (this *ContractInfo) Equal(that interface{}) bool { if !bytes.Equal(this.Admin, that1.Admin) { return false } + if !bytes.Equal(this.AdminProof, that1.AdminProof) { + return false + } return true } func (this *AbsoluteTxPosition) Equal(that interface{}) bool { @@ -785,6 +927,85 @@ func (m *ContractCustomInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *ContractKey) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ContractKey) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ContractKey) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Original != nil { + { + size, err := m.Original.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Key) > 0 { + i -= len(m.Key) + copy(dAtA[i:], m.Key) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Key))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ContractKeyWithProof) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ContractKeyWithProof) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ContractKeyWithProof) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Proof) > 0 { + i -= len(m.Proof) + copy(dAtA[i:], m.Proof) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Proof))) + i-- + dAtA[i] = 0x12 + } + if len(m.Key) > 0 { + i -= len(m.Key) + copy(dAtA[i:], m.Key) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Key))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *ContractInfo) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -805,6 +1026,13 @@ func (m *ContractInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.AdminProof) > 0 { + i -= len(m.AdminProof) + copy(dAtA[i:], m.AdminProof) + i = encodeVarintTypes(dAtA, i, uint64(len(m.AdminProof))) + i-- + dAtA[i] = 0x42 + } if len(m.Admin) > 0 { i -= len(m.Admin) copy(dAtA[i:], m.Admin) @@ -1040,6 +1268,40 @@ func (m *ContractCustomInfo) Size() (n int) { return n } +func (m *ContractKey) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Key) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.Original != nil { + l = m.Original.Size() + n += 1 + l + sovTypes(uint64(l)) + } + return n +} + +func (m *ContractKeyWithProof) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Key) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.Proof) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + return n +} + func (m *ContractInfo) Size() (n int) { if m == nil { return 0 @@ -1069,6 +1331,10 @@ func (m *ContractInfo) Size() (n int) { if l > 0 { n += 1 + l + sovTypes(uint64(l)) } + l = len(m.AdminProof) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } return n } @@ -1500,6 +1766,244 @@ func (m *ContractCustomInfo) Unmarshal(dAtA []byte) error { } return nil } +func (m *ContractKey) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ContractKey: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ContractKey: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Key = append(m.Key[:0], dAtA[iNdEx:postIndex]...) + if m.Key == nil { + m.Key = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Original", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Original == nil { + m.Original = &ContractKeyWithProof{} + } + if err := m.Original.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ContractKeyWithProof) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ContractKeyWithProof: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ContractKeyWithProof: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Key = append(m.Key[:0], dAtA[iNdEx:postIndex]...) + if m.Key == nil { + m.Key = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Proof", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Proof = append(m.Proof[:0], dAtA[iNdEx:postIndex]...) + if m.Proof == nil { + m.Proof = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *ContractInfo) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -1716,6 +2220,40 @@ func (m *ContractInfo) Unmarshal(dAtA []byte) error { m.Admin = []byte{} } iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AdminProof", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AdminProof = append(m.AdminProof[:0], dAtA[iNdEx:postIndex]...) + if m.AdminProof == nil { + m.AdminProof = []byte{} + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) From 9e5d9307b7a8449ae74d7fbfbe9503ee60e02138 Mon Sep 17 00:00:00 2001 From: Itzik Grossman Date: Tue, 23 May 2023 17:26:04 +0300 Subject: [PATCH 009/164] Basic migrate works:) (...other tests kind of broken still, but hey, progress) --- .../src/benches/read_storage.rs | 4 +- .../src/benches/write_storage.rs | 2 +- .../migration/contract-v1/Cargo.lock | 691 ++++++++++ .../migration/contract-v1/Cargo.toml | 55 + .../migration/contract-v1/Makefile | 9 + .../migration/contract-v1/src/contract.rs | 24 + .../migration/contract-v1/src/lib.rs | 2 + .../migration/contract-v1/src/msg.rs | 13 + .../migration/contract-v2/Cargo.lock | 691 ++++++++++ .../migration/contract-v2/Cargo.toml | 55 + .../migration/contract-v2/Makefile | 9 + .../migration/contract-v2/src/contract.rs | 31 + .../migration/contract-v2/src/lib.rs | 2 + .../migration/contract-v2/src/msg.rs | 19 + cosmwasm/enclaves/execute/Enclave.edl | 2 +- cosmwasm/enclaves/ffi-types/cbindgen.toml | 1 + .../src/contract_operations.rs | 29 +- .../src/contract_validation.rs | 3 + .../enclaves/shared/contract-engine/src/io.rs | 140 +- .../shared/contract-engine/src/wasm3/mod.rs | 37 +- .../contract-engine/src/wasm3/module_cache.rs | 20 +- .../shared/cosmos-proto/src/cosmwasm/msg.rs | 1209 ++++++++++++++++- .../enclaves/shared/cosmos-types/src/types.rs | 51 +- .../shared/cosmwasm-types/generic/src/lib.rs | 4 +- .../shared/cosmwasm-types/v0.10/src/types.rs | 10 +- go-cosmwasm/api/lib.go | 2 +- go-cosmwasm/types/env.go | 8 +- proto/secret/compute/v1beta1/msg.proto | 1 + .../internal/keeper/distribution_test.go | 2 +- x/compute/internal/keeper/keeper.go | 50 +- .../keeper/param_verification_test.go | 26 +- .../keeper/secret_contracts_exec_test.go | 5 +- .../keeper/secret_contracts_migrate_test.go | 28 + .../keeper/secret_contracts_utils_test.go | 88 +- x/compute/internal/keeper/test_common.go | 30 + .../keeper/testdata/bench_contract.wasm | Bin 778791 -> 802865 bytes x/compute/internal/types/codec.go | 1 + x/compute/internal/types/msg.pb.go | 140 +- x/compute/internal/types/types.go | 23 +- 39 files changed, 3293 insertions(+), 224 deletions(-) create mode 100644 cosmwasm/contracts/v1/compute-tests/migration/contract-v1/Cargo.lock create mode 100644 cosmwasm/contracts/v1/compute-tests/migration/contract-v1/Cargo.toml create mode 100644 cosmwasm/contracts/v1/compute-tests/migration/contract-v1/Makefile create mode 100644 cosmwasm/contracts/v1/compute-tests/migration/contract-v1/src/contract.rs create mode 100644 cosmwasm/contracts/v1/compute-tests/migration/contract-v1/src/lib.rs create mode 100644 cosmwasm/contracts/v1/compute-tests/migration/contract-v1/src/msg.rs create mode 100644 cosmwasm/contracts/v1/compute-tests/migration/contract-v2/Cargo.lock create mode 100644 cosmwasm/contracts/v1/compute-tests/migration/contract-v2/Cargo.toml create mode 100644 cosmwasm/contracts/v1/compute-tests/migration/contract-v2/Makefile create mode 100644 cosmwasm/contracts/v1/compute-tests/migration/contract-v2/src/contract.rs create mode 100644 cosmwasm/contracts/v1/compute-tests/migration/contract-v2/src/lib.rs create mode 100644 cosmwasm/contracts/v1/compute-tests/migration/contract-v2/src/msg.rs create mode 100644 x/compute/internal/keeper/secret_contracts_migrate_test.go diff --git a/cosmwasm/contracts/v1/compute-tests/bench-contract/src/benches/read_storage.rs b/cosmwasm/contracts/v1/compute-tests/bench-contract/src/benches/read_storage.rs index 74825fc36..935f2557e 100644 --- a/cosmwasm/contracts/v1/compute-tests/bench-contract/src/benches/read_storage.rs +++ b/cosmwasm/contracts/v1/compute-tests/bench-contract/src/benches/read_storage.rs @@ -16,8 +16,8 @@ pub fn bench_read_storage_same_key(deps: DepsMut, keys: u64) -> StdResult<()> { /// call this test only after setting up the test with write storage, so the keys are populated pub fn bench_read_storage_different_key(deps: DepsMut, keys: u64) -> StdResult<()> { - for i in 0..keys { - deps.storage.get(&i.to_be_bytes()).unwrap(); + for i in 1..keys { + deps.storage.get(&i.to_be_bytes()); } Ok(()) diff --git a/cosmwasm/contracts/v1/compute-tests/bench-contract/src/benches/write_storage.rs b/cosmwasm/contracts/v1/compute-tests/bench-contract/src/benches/write_storage.rs index bb107f3c4..815982a93 100644 --- a/cosmwasm/contracts/v1/compute-tests/bench-contract/src/benches/write_storage.rs +++ b/cosmwasm/contracts/v1/compute-tests/bench-contract/src/benches/write_storage.rs @@ -10,7 +10,7 @@ pub fn bench_write_storage_same_key(deps: DepsMut, keys: u64) -> StdResult<()> { } pub fn bench_write_storage_different_key(deps: DepsMut, keys: u64) -> StdResult<()> { - for i in 1..keys { + for i in 0..keys { deps.storage.set(&i.to_be_bytes(), i.to_string().as_bytes()); } diff --git a/cosmwasm/contracts/v1/compute-tests/migration/contract-v1/Cargo.lock b/cosmwasm/contracts/v1/compute-tests/migration/contract-v1/Cargo.lock new file mode 100644 index 000000000..def1b0a4e --- /dev/null +++ b/cosmwasm/contracts/v1/compute-tests/migration/contract-v1/Cargo.lock @@ -0,0 +1,691 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "const-oid" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" + +[[package]] +name = "cosmwasm-crypto" +version = "1.1.9" +source = "git+https://github.com/scrtlabs/cosmwasm?rev=97122ddc6e1b2a57e2b966f6b0663df95ed5d82b#97122ddc6e1b2a57e2b966f6b0663df95ed5d82b" +dependencies = [ + "digest 0.10.6", + "ed25519-zebra", + "k256", + "rand_core 0.6.4", + "thiserror", +] + +[[package]] +name = "cosmwasm-derive" +version = "1.1.9" +source = "git+https://github.com/scrtlabs/cosmwasm?rev=97122ddc6e1b2a57e2b966f6b0663df95ed5d82b#97122ddc6e1b2a57e2b966f6b0663df95ed5d82b" +dependencies = [ + "syn 1.0.109", +] + +[[package]] +name = "cosmwasm-schema" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe5ad2e23a971b9e4cd57b20cee3e2e79c33799bed4b128e473aca3702bfe5dd" +dependencies = [ + "cosmwasm-schema-derive", + "schemars", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cosmwasm-schema-derive" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2926d159a9bb1a716a592b40280f1663f2491a9de3b6da77c0933cee2a2655b8" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cosmwasm-std" +version = "1.1.9" +source = "git+https://github.com/scrtlabs/cosmwasm?rev=97122ddc6e1b2a57e2b966f6b0663df95ed5d82b#97122ddc6e1b2a57e2b966f6b0663df95ed5d82b" +dependencies = [ + "base64", + "cosmwasm-crypto", + "cosmwasm-derive", + "derivative", + "forward_ref", + "hex", + "schemars", + "serde", + "serde-json-wasm", + "thiserror", + "uint", +] + +[[package]] +name = "cosmwasm-storage" +version = "1.1.9" +source = "git+https://github.com/scrtlabs/cosmwasm?rev=97122ddc6e1b2a57e2b966f6b0663df95ed5d82b#97122ddc6e1b2a57e2b966f6b0663df95ed5d82b" +dependencies = [ + "cosmwasm-std", + "serde", +] + +[[package]] +name = "cpufeatures" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181" +dependencies = [ + "libc", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer 0.10.4", + "crypto-common", + "subtle", +] + +[[package]] +name = "dyn-clone" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30" + +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der", + "elliptic-curve", + "rfc6979", + "signature", +] + +[[package]] +name = "ed25519-zebra" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c24f403d068ad0b359e577a77f92392118be3f3c927538f2bb544a5ecd828c6" +dependencies = [ + "curve25519-dalek", + "hashbrown", + "hex", + "rand_core 0.6.4", + "serde", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct", + "crypto-bigint", + "der", + "digest 0.10.6", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "forward_ref" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.6", +] + +[[package]] +name = "itoa" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" + +[[package]] +name = "k256" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "sha2 0.10.6", +] + +[[package]] +name = "libc" +version = "0.2.140" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" + +[[package]] +name = "migrate_contract_v1" +version = "0.1.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cosmwasm-storage", + "schemars", + "serde", +] + +[[package]] +name = "once_cell" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "proc-macro2" +version = "1.0.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e472a104799c74b514a57226160104aa483546de37e839ec50e3c2e41dd87534" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint", + "hmac", + "zeroize", +] + +[[package]] +name = "ryu" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" + +[[package]] +name = "schemars" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02c613288622e5f0c3fdc5dbd4db1c5fbe752746b1d1a56a0630b78fd00de44f" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "109da1e6b197438deb6db99952990c7f959572794b80ff93707d55a232545e7c" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 1.0.109", +] + +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "serde" +version = "1.0.159" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-json-wasm" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.159" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.11", +] + +[[package]] +name = "serde_derive_internals" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "serde_json" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.6", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest 0.10.6", + "rand_core 0.6.4", +] + +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21e3787bb71465627110e7d87ed4faaa36c1f61042ee67badb9e2ef173accc40" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.11", +] + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unicode-ident" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "zeroize" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/cosmwasm/contracts/v1/compute-tests/migration/contract-v1/Cargo.toml b/cosmwasm/contracts/v1/compute-tests/migration/contract-v1/Cargo.toml new file mode 100644 index 000000000..7cad361d6 --- /dev/null +++ b/cosmwasm/contracts/v1/compute-tests/migration/contract-v1/Cargo.toml @@ -0,0 +1,55 @@ +[package] +name = "migrate_contract_v1" +version = "0.1.0" +authors = ["Itzik Grossman"] +edition = "2018" + +exclude = [ + # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. + "contract.wasm", + "hash.txt", +] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +crate-type = ["cdylib", "rlib"] + +[profile.release] +opt-level = 3 +debug = false +rpath = false +lto = true +debug-assertions = false +codegen-units = 1 +panic = 'abort' +incremental = false +overflow-checks = true + +[features] +default = [] +# for quicker tests, cargo test --lib +# for more explicit tests, cargo test --features=backtraces +backtraces = ["cosmwasm-std/backtraces"] +schema = ["cosmwasm-schema"] + +[dependencies] +serde = { version = "1.0.147", default-features = false, features = ["derive"] } +schemars = "0.8.11" +cosmwasm-std = { version = "1.0.0" } +cosmwasm-storage = { version = "1.0.0" } + +# Used only for schema generation +cosmwasm-schema = { version = "1.1.0", optional = true } + +# Uncomment these for some common extra tools +# secret-toolkit = "0.7.0" +# cw-storage-plus = { version = "0.14.0", default-features = false } + +[patch.crates-io] +#cosmwasm-std = { git = "https://github.com/scrtlabs/cosmwasm", rev = "f7e2b1dbf11e113e258d796288752503a5012367", package = "cosmwasm-std" } +#cosmwasm-storage = { git = "https://github.com/scrtlabs/cosmwasm", rev = "f7e2b1dbf11e113e258d796288752503a5012367", package = "cosmwasm-storage" } + +cosmwasm-std = { git = "https://github.com/scrtlabs/cosmwasm", rev = "97122ddc6e1b2a57e2b966f6b0663df95ed5d82b" } +cosmwasm-storage = { git = "https://github.com/scrtlabs/cosmwasm", rev = "97122ddc6e1b2a57e2b966f6b0663df95ed5d82b" } + diff --git a/cosmwasm/contracts/v1/compute-tests/migration/contract-v1/Makefile b/cosmwasm/contracts/v1/compute-tests/migration/contract-v1/Makefile new file mode 100644 index 000000000..a876f0e68 --- /dev/null +++ b/cosmwasm/contracts/v1/compute-tests/migration/contract-v1/Makefile @@ -0,0 +1,9 @@ +all: src/contract.rs src src src Cargo.toml Cargo.lock + rustup target add wasm32-unknown-unknown + RUSTFLAGS='-C link-arg=-s' cargo build --release --target wasm32-unknown-unknown + cp ./target/wasm32-unknown-unknown/release/migrate_contract_v1.wasm ./migrate_contract_v1.wasm + cp ./target/wasm32-unknown-unknown/release/migrate_contract_v1.wasm ../../../../../../x/compute/internal/keeper/testdata/migrate_contract_v1.wasm + +clean: + cargo clean + -rm -f ./v1-contract.wasm diff --git a/cosmwasm/contracts/v1/compute-tests/migration/contract-v1/src/contract.rs b/cosmwasm/contracts/v1/compute-tests/migration/contract-v1/src/contract.rs new file mode 100644 index 000000000..197d54d69 --- /dev/null +++ b/cosmwasm/contracts/v1/compute-tests/migration/contract-v1/src/contract.rs @@ -0,0 +1,24 @@ +use crate::msg::{ExecuteMsg, InstantiateMsg}; +use cosmwasm_std::{entry_point, DepsMut, Env, MessageInfo, Response, StdResult}; + +#[entry_point] +pub fn instantiate( + _deps: DepsMut, + _env: Env, + _info: MessageInfo, + _msg: InstantiateMsg, +) -> StdResult { + Ok(Response::default()) +} + +#[entry_point] +pub fn execute( + deps: DepsMut, + _env: Env, + _info: MessageInfo, + msg: ExecuteMsg, +) -> StdResult { + match msg { + ExecuteMsg::Test {} => Ok(Response::default()), + } +} diff --git a/cosmwasm/contracts/v1/compute-tests/migration/contract-v1/src/lib.rs b/cosmwasm/contracts/v1/compute-tests/migration/contract-v1/src/lib.rs new file mode 100644 index 000000000..112ecadc8 --- /dev/null +++ b/cosmwasm/contracts/v1/compute-tests/migration/contract-v1/src/lib.rs @@ -0,0 +1,2 @@ +pub mod contract; +pub mod msg; diff --git a/cosmwasm/contracts/v1/compute-tests/migration/contract-v1/src/msg.rs b/cosmwasm/contracts/v1/compute-tests/migration/contract-v1/src/msg.rs new file mode 100644 index 000000000..75637f0c3 --- /dev/null +++ b/cosmwasm/contracts/v1/compute-tests/migration/contract-v1/src/msg.rs @@ -0,0 +1,13 @@ +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, JsonSchema)] +pub enum InstantiateMsg { + Nop {}, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum ExecuteMsg { + Test { }, +} diff --git a/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/Cargo.lock b/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/Cargo.lock new file mode 100644 index 000000000..44d43a38c --- /dev/null +++ b/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/Cargo.lock @@ -0,0 +1,691 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "const-oid" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" + +[[package]] +name = "cosmwasm-crypto" +version = "1.1.9" +source = "git+https://github.com/scrtlabs/cosmwasm?rev=97122ddc6e1b2a57e2b966f6b0663df95ed5d82b#97122ddc6e1b2a57e2b966f6b0663df95ed5d82b" +dependencies = [ + "digest 0.10.6", + "ed25519-zebra", + "k256", + "rand_core 0.6.4", + "thiserror", +] + +[[package]] +name = "cosmwasm-derive" +version = "1.1.9" +source = "git+https://github.com/scrtlabs/cosmwasm?rev=97122ddc6e1b2a57e2b966f6b0663df95ed5d82b#97122ddc6e1b2a57e2b966f6b0663df95ed5d82b" +dependencies = [ + "syn 1.0.109", +] + +[[package]] +name = "cosmwasm-schema" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe5ad2e23a971b9e4cd57b20cee3e2e79c33799bed4b128e473aca3702bfe5dd" +dependencies = [ + "cosmwasm-schema-derive", + "schemars", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cosmwasm-schema-derive" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2926d159a9bb1a716a592b40280f1663f2491a9de3b6da77c0933cee2a2655b8" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cosmwasm-std" +version = "1.1.9" +source = "git+https://github.com/scrtlabs/cosmwasm?rev=97122ddc6e1b2a57e2b966f6b0663df95ed5d82b#97122ddc6e1b2a57e2b966f6b0663df95ed5d82b" +dependencies = [ + "base64", + "cosmwasm-crypto", + "cosmwasm-derive", + "derivative", + "forward_ref", + "hex", + "schemars", + "serde", + "serde-json-wasm", + "thiserror", + "uint", +] + +[[package]] +name = "cosmwasm-storage" +version = "1.1.9" +source = "git+https://github.com/scrtlabs/cosmwasm?rev=97122ddc6e1b2a57e2b966f6b0663df95ed5d82b#97122ddc6e1b2a57e2b966f6b0663df95ed5d82b" +dependencies = [ + "cosmwasm-std", + "serde", +] + +[[package]] +name = "cpufeatures" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181" +dependencies = [ + "libc", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer 0.10.4", + "crypto-common", + "subtle", +] + +[[package]] +name = "dyn-clone" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30" + +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der", + "elliptic-curve", + "rfc6979", + "signature", +] + +[[package]] +name = "ed25519-zebra" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c24f403d068ad0b359e577a77f92392118be3f3c927538f2bb544a5ecd828c6" +dependencies = [ + "curve25519-dalek", + "hashbrown", + "hex", + "rand_core 0.6.4", + "serde", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct", + "crypto-bigint", + "der", + "digest 0.10.6", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "forward_ref" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.6", +] + +[[package]] +name = "itoa" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" + +[[package]] +name = "k256" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "sha2 0.10.6", +] + +[[package]] +name = "libc" +version = "0.2.140" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" + +[[package]] +name = "migrate_contract_v2" +version = "0.1.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cosmwasm-storage", + "schemars", + "serde", +] + +[[package]] +name = "once_cell" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "proc-macro2" +version = "1.0.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e472a104799c74b514a57226160104aa483546de37e839ec50e3c2e41dd87534" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint", + "hmac", + "zeroize", +] + +[[package]] +name = "ryu" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" + +[[package]] +name = "schemars" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02c613288622e5f0c3fdc5dbd4db1c5fbe752746b1d1a56a0630b78fd00de44f" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "109da1e6b197438deb6db99952990c7f959572794b80ff93707d55a232545e7c" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 1.0.109", +] + +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "serde" +version = "1.0.159" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-json-wasm" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.159" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.11", +] + +[[package]] +name = "serde_derive_internals" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "serde_json" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.6", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest 0.10.6", + "rand_core 0.6.4", +] + +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21e3787bb71465627110e7d87ed4faaa36c1f61042ee67badb9e2ef173accc40" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.11", +] + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unicode-ident" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "zeroize" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/Cargo.toml b/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/Cargo.toml new file mode 100644 index 000000000..75f64b4b9 --- /dev/null +++ b/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/Cargo.toml @@ -0,0 +1,55 @@ +[package] +name = "migrate_contract_v2" +version = "0.1.0" +authors = ["Itzik Grossman"] +edition = "2018" + +exclude = [ + # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. + "contract.wasm", + "hash.txt", +] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +crate-type = ["cdylib", "rlib"] + +[profile.release] +opt-level = 3 +debug = false +rpath = false +lto = true +debug-assertions = false +codegen-units = 1 +panic = 'abort' +incremental = false +overflow-checks = true + +[features] +default = [] +# for quicker tests, cargo test --lib +# for more explicit tests, cargo test --features=backtraces +backtraces = ["cosmwasm-std/backtraces"] +schema = ["cosmwasm-schema"] + +[dependencies] +serde = { version = "1.0.147", default-features = false, features = ["derive"] } +schemars = "0.8.11" +cosmwasm-std = { version = "1.0.0" } +cosmwasm-storage = { version = "1.0.0" } + +# Used only for schema generation +cosmwasm-schema = { version = "1.1.0", optional = true } + +# Uncomment these for some common extra tools +# secret-toolkit = "0.7.0" +# cw-storage-plus = { version = "0.14.0", default-features = false } + +[patch.crates-io] +#cosmwasm-std = { git = "https://github.com/scrtlabs/cosmwasm", rev = "f7e2b1dbf11e113e258d796288752503a5012367", package = "cosmwasm-std" } +#cosmwasm-storage = { git = "https://github.com/scrtlabs/cosmwasm", rev = "f7e2b1dbf11e113e258d796288752503a5012367", package = "cosmwasm-storage" } + +cosmwasm-std = { git = "https://github.com/scrtlabs/cosmwasm", rev = "97122ddc6e1b2a57e2b966f6b0663df95ed5d82b" } +cosmwasm-storage = { git = "https://github.com/scrtlabs/cosmwasm", rev = "97122ddc6e1b2a57e2b966f6b0663df95ed5d82b" } + diff --git a/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/Makefile b/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/Makefile new file mode 100644 index 000000000..79231f421 --- /dev/null +++ b/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/Makefile @@ -0,0 +1,9 @@ +all: src/contract.rs src src src Cargo.toml Cargo.lock + rustup target add wasm32-unknown-unknown + RUSTFLAGS='-C link-arg=-s' cargo build --release --target wasm32-unknown-unknown + cp ./target/wasm32-unknown-unknown/release/migrate_contract_v2.wasm ./migrate_contract_v2.wasm + cp ./target/wasm32-unknown-unknown/release/migrate_contract_v2.wasm ../../../../../../x/compute/internal/keeper/testdata/migrate_contract_v2.wasm + +clean: + cargo clean + -rm -f ./v1-contract.wasm diff --git a/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/src/contract.rs b/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/src/contract.rs new file mode 100644 index 000000000..15703f81f --- /dev/null +++ b/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/src/contract.rs @@ -0,0 +1,31 @@ +use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg}; +use cosmwasm_std::{entry_point, DepsMut, Env, MessageInfo, Response, StdResult}; + +#[entry_point] +pub fn instantiate( + _deps: DepsMut, + _env: Env, + _info: MessageInfo, + _msg: InstantiateMsg, +) -> StdResult { + Ok(Response::default()) +} + +#[entry_point] +pub fn execute( + deps: DepsMut, + _env: Env, + _info: MessageInfo, + msg: ExecuteMsg, +) -> StdResult { + match msg { + ExecuteMsg::NewFunction {} => Ok(Response::default()), + } +} + +#[entry_point] +pub fn migrate(_deps: DepsMut, _env: Env, msg: MigrateMsg) -> StdResult { + match msg { + MigrateMsg::Migrate {} => Ok(Response::default()), + } +} diff --git a/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/src/lib.rs b/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/src/lib.rs new file mode 100644 index 000000000..112ecadc8 --- /dev/null +++ b/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/src/lib.rs @@ -0,0 +1,2 @@ +pub mod contract; +pub mod msg; diff --git a/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/src/msg.rs b/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/src/msg.rs new file mode 100644 index 000000000..effb5c93a --- /dev/null +++ b/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/src/msg.rs @@ -0,0 +1,19 @@ +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, JsonSchema)] +pub enum InstantiateMsg { + Nop {}, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum ExecuteMsg { + NewFunction {}, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum MigrateMsg { + Migrate {}, +} diff --git a/cosmwasm/enclaves/execute/Enclave.edl b/cosmwasm/enclaves/execute/Enclave.edl index 7aba2a93b..bd11407ed 100644 --- a/cosmwasm/enclaves/execute/Enclave.edl +++ b/cosmwasm/enclaves/execute/Enclave.edl @@ -106,7 +106,7 @@ enclave { uintptr_t msg_len ); - public HandleResult ecall_migrate( + public MigrateResult ecall_migrate( Ctx context, uint64_t gas_limit, [out] uint64_t* used_gas, diff --git a/cosmwasm/enclaves/ffi-types/cbindgen.toml b/cosmwasm/enclaves/ffi-types/cbindgen.toml index 2f13f1c5c..88ad73974 100644 --- a/cosmwasm/enclaves/ffi-types/cbindgen.toml +++ b/cosmwasm/enclaves/ffi-types/cbindgen.toml @@ -36,6 +36,7 @@ include = [ "Ctx", "InitResult", "HandleResult", + "MigrateResult", "QueryResult", "OcallReturn", "HealthCheckResult", diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 22461da95..a76a8e377 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -93,6 +93,10 @@ pub fn init( let contract_hash = contract_code.hash(); // let duration = start.elapsed(); // trace!("Time elapsed in ContractCode::new is: {:?}", duration); + debug!( + "******************** init RUNNING WITH CODE: {:?}", + contract_hash + ); //let start = Instant::now(); let base_env: BaseEnv = extract_base_env(env)?; @@ -255,13 +259,17 @@ pub fn migrate( admin: &[u8], admin_proof: &[u8], ) -> Result { - trace!("Starting init"); + debug!("Starting migrate"); //let start = Instant::now(); let contract_code = ContractCode::new(contract); let contract_hash = contract_code.hash(); // let duration = start.elapsed(); // trace!("Time elapsed in ContractCode::new is: {:?}", duration); + debug!( + "******************** migrate RUNNING WITH CODE: {:?}", + contract_hash + ); //let start = Instant::now(); let base_env: BaseEnv = extract_base_env(env)?; @@ -357,10 +365,7 @@ pub fn migrate( set_random_in_env(block_height, &contract_key, &mut engine, &mut versioned_env); update_msg_counter(block_height); - //let start = Instant::now(); let result = engine.migrate(&versioned_env, validated_msg); - // let duration = start.elapsed(); - // trace!("Time elapsed in engine.init: {:?}", duration); *used_gas = engine.gas_used(); @@ -370,11 +375,6 @@ pub fn migrate( .flush_cache() .map_err(|_| EnclaveError::FailedFunctionCall)?; - // TODO: copy cosmwasm's structures to enclave - // TODO: ref: https://github.com/CosmWasm/cosmwasm/blob/b971c037a773bf6a5f5d08a88485113d9b9e8e7b/packages/std/src/init_handle.rs#L129 - // TODO: ref: https://github.com/CosmWasm/cosmwasm/blob/b971c037a773bf6a5f5d08a88485113d9b9e8e7b/packages/std/src/query.rs#L13 - //let start = Instant::now(); - let output = post_process_output( output, &secret_msg, @@ -391,6 +391,11 @@ pub fn migrate( // todo: can move the key to somewhere in the output message if we want + debug!( + "Migrate success: {:?}, {:?}", + contract_key, contract_key_proof + ); + Ok(MigrateSuccess { output, new_contract_key: contract_key, @@ -414,6 +419,11 @@ pub fn handle( let contract_code = ContractCode::new(contract); let contract_hash = contract_code.hash(); + debug!( + "******************** HANDLE RUNNING WITH CODE: {:?}", + contract_hash + ); + let base_env: BaseEnv = extract_base_env(env)?; #[cfg(feature = "light-client-validation")] @@ -432,6 +442,7 @@ pub fn handle( validate_contract_key(&contract_key, &canonical_contract_address, &contract_code)?; if base_env.was_migrated() { + println!("Contract was migrated, setting keys to original one"); let og_key = base_env.get_original_contract_key().unwrap(); // was_migrated checks that this won't fail contract_key = og_key.get_key(); diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index f66648259..880fb6b0b 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -591,6 +591,7 @@ fn get_verified_msg<'sd>( ) -> Option<&'sd CosmWasmMsg> { messages.iter().find(|&m| match m { CosmWasmMsg::Execute { msg, sender, .. } + | CosmWasmMsg::Migrate { msg, sender } | CosmWasmMsg::Instantiate { init_msg: msg, sender, @@ -617,6 +618,7 @@ fn verify_contract(msg: &CosmWasmMsg, contract_address: &HumanAddr) -> bool { is_verified } CosmWasmMsg::Instantiate { .. } => true, + CosmWasmMsg::Migrate { .. } => true, CosmWasmMsg::Other => false, } } @@ -630,6 +632,7 @@ fn verify_funds(msg: &CosmWasmMsg, sent_funds_msg: &[Coin]) -> bool { .. } => sent_funds_msg == sent_funds, CosmWasmMsg::Other => false, + CosmWasmMsg::Migrate { .. } => true, } } diff --git a/cosmwasm/enclaves/shared/contract-engine/src/io.rs b/cosmwasm/enclaves/shared/contract-engine/src/io.rs index be809d946..84ff98b4b 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/io.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/io.rs @@ -1,5 +1,5 @@ -use core::fmt; use crate::contract_validation::ReplyParams; +use core::fmt; /// This contains all the user-facing functions. In these functions we will be using /// the consensus_io_exchange_keypair and a user-generated key to create a symmetric key @@ -130,7 +130,7 @@ pub fn calc_encryption_key(nonce: &IoNonce, user_public_key: &Ed25519PublicKey) let tx_encryption_key = AESKey::new_from_slice(&tx_encryption_ikm).derive_key_from_this(nonce); - trace!("rust tx_encryption_key {:?}", tx_encryption_key.get()); + // trace!("rust tx_encryption_key {:?}", tx_encryption_key.get()); tx_encryption_key } @@ -241,7 +241,7 @@ pub fn finalize_raw_output( is_query_output: bool, is_ibc: bool, is_msg_encrypted: bool, -) -> Result , EnclaveError> { +) -> Result, EnclaveError> { let mut wasm_output = WasmOutput::default(); match raw_output { @@ -280,7 +280,7 @@ pub fn finalize_raw_output( }); wasm_output.internal_reply_enclave_sig = internal_reply_enclave_sig; wasm_output.internal_msg_id = internal_msg_id; - }, + } RawWasmOutput::OkV1 { ok, internal_reply_enclave_sig, @@ -304,19 +304,19 @@ pub fn finalize_raw_output( ok: Some(ok), }); } - }, + } RawWasmOutput::QueryOkV010 { ok } | RawWasmOutput::QueryOkV1 { ok } => { wasm_output.query = Some(QueryOutput { ok: Some(ok), err: None, }); - }, + } RawWasmOutput::OkIBCPacketReceive { ok } => { wasm_output.ibc_packet_receive = Some(IBCReceiveOutput { err: None, ok: Some(ok), }); - }, + } RawWasmOutput::OkIBCOpenChannel { ok } => { wasm_output.ibc_open_channel = Some(IBCOpenChannelOutput { err: None, @@ -446,14 +446,15 @@ pub fn set_all_logs_to_plaintext(raw_output: &mut RawWasmOutput) { } } -fn deserialize_output( - output: Vec -) -> Result { - info!("output as received from contract: {:?}", String::from_utf8_lossy(&output)); +fn deserialize_output(output: Vec) -> Result { + trace!( + "output as received from contract: {:?}", + String::from_utf8_lossy(&output) + ); let output: RawWasmOutput = serde_json::from_slice(&output).map_err(|err| { warn!("got an error while trying to deserialize output bytes from json"); - trace!("output: {:?} error: {:?}", output, err); + debug!("output: {:?} error: {:?}", output, err); EnclaveError::FailedToDeserialize })?; @@ -487,8 +488,7 @@ fn encrypt_output( let encryption_key = calc_encryption_key(&secret_msg.nonce, &secret_msg.user_public_key); info!( "message nonce and public key for encryption: {:?} {:?}", - secret_msg.nonce, - secret_msg.user_public_key + secret_msg.nonce, secret_msg.user_public_key ); match &mut output { @@ -529,7 +529,12 @@ fn encrypt_output( } } RawWasmOutput::OkV1 { ok, .. } => { - encrypt_v1_non_result_fields(&mut ok.messages, &mut ok.attributes, &mut ok.events, secret_msg)?; + encrypt_v1_non_result_fields( + &mut ok.messages, + &mut ok.attributes, + &mut ok.events, + secret_msg, + )?; if let Some(data) = &mut ok.data { if is_ibc_output { warn!("IBC output should not contain any data"); @@ -545,7 +550,12 @@ fn encrypt_output( } } RawWasmOutput::OkIBCPacketReceive { ok } => { - encrypt_v1_non_result_fields(&mut ok.messages, &mut ok.attributes, &mut ok.events, secret_msg)?; + encrypt_v1_non_result_fields( + &mut ok.messages, + &mut ok.attributes, + &mut ok.events, + secret_msg, + )?; ok.acknowledgement = Binary::from_base64(&encrypt_serializable( &encryption_key, @@ -575,17 +585,14 @@ fn encrypt_v1_non_result_fields( // v1: The attributes that will be emitted as part of a "wasm" event. for attr in attributes.iter_mut().filter(|attr| attr.encrypted) { attr.key = encrypt_preserialized_string(&encryption_key, &attr.key, &None, false)?; - attr.value = - encrypt_preserialized_string(&encryption_key, &attr.value, &None, false)?; + attr.value = encrypt_preserialized_string(&encryption_key, &attr.value, &None, false)?; } // v1: Extra, custom events separate from the main wasm one. These will have "wasm-"" prepended to the type. for event in events.iter_mut() { for attr in event.attributes.iter_mut().filter(|attr| attr.encrypted) { - attr.key = - encrypt_preserialized_string(&encryption_key, &attr.key, &None, false)?; - attr.value = - encrypt_preserialized_string(&encryption_key, &attr.value, &None, false)?; + attr.key = encrypt_preserialized_string(&encryption_key, &attr.key, &None, false)?; + attr.value = encrypt_preserialized_string(&encryption_key, &attr.value, &None, false)?; } } @@ -599,8 +606,8 @@ fn encrypt_wasm_submsg( // Messages other than Wasm (Bank, Staking, etc.) are kept plaintext if let cw_types_v1::results::CosmosMsg::Wasm(wasm_msg) = &mut sub_msg.msg { match wasm_msg { - cw_types_v1::results::WasmMsg::Instantiate { msg, .. } | - cw_types_v1::results::WasmMsg::Execute { msg, .. } => { + cw_types_v1::results::WasmMsg::Instantiate { msg, .. } + | cw_types_v1::results::WasmMsg::Execute { msg, .. } => { let mut msg_to_encrypt = SecretMessage { msg: msg.as_slice().to_vec(), nonce: secret_msg.nonce, @@ -632,13 +639,9 @@ fn attach_reply_headers_to_submsgs( reply_params: &Option>, ) -> Result { let sub_msgs = match &mut output { - RawWasmOutput::OkV1 { ok, .. } => { - &mut ok.messages - }, - RawWasmOutput::OkIBCPacketReceive { ok } => { - &mut ok.messages - }, - _ => return Ok(output) + RawWasmOutput::OkV1 { ok, .. } => &mut ok.messages, + RawWasmOutput::OkIBCPacketReceive { ok } => &mut ok.messages, + _ => return Ok(output), }; for sub_msg in sub_msgs { @@ -675,20 +678,26 @@ fn create_callback_sig_for_submsgs( contract_addr: &CanonicalAddr, ) -> Result { let sub_msgs = match &mut output { - RawWasmOutput::OkV1 { ok, .. } => { - &mut ok.messages - }, - RawWasmOutput::OkIBCPacketReceive { ok } => { - &mut ok.messages - }, - _ => return Ok(output) + RawWasmOutput::OkV1 { ok, .. } => &mut ok.messages, + RawWasmOutput::OkIBCPacketReceive { ok } => &mut ok.messages, + _ => return Ok(output), }; for sub_msg in sub_msgs { if let cw_types_v1::results::CosmosMsg::Wasm(wasm_msg) = &mut sub_msg.msg { match wasm_msg { - cw_types_v1::results::WasmMsg::Execute { msg, callback_sig, funds, .. } - | cw_types_v1::results::WasmMsg::Instantiate { msg, callback_sig, funds, .. } => { + cw_types_v1::results::WasmMsg::Execute { + msg, + callback_sig, + funds, + .. + } + | cw_types_v1::results::WasmMsg::Instantiate { + msg, + callback_sig, + funds, + .. + } => { *callback_sig = Some(create_callback_signature( contract_addr, &SecretMessage::from_slice(msg.as_slice())?.msg, @@ -708,7 +717,6 @@ fn create_callback_sig_for_submsgs( Ok(output) } - /// Adapt the output of a contract to be returned as a Reply message. /// If the contract's execution was not called from another contract, the output is returned as is. /// Otherwise, the fields `internal_msg_id` and `internal_reply_enclave_sig` of the output are populated. @@ -731,7 +739,7 @@ fn adapt_output_for_reply( if reply_params.is_none() { // This message was not called from another contract, // no need to adapt output as a reply - return Ok(output) + return Ok(output); } let encryption_key = calc_encryption_key(&secret_msg.nonce, &secret_msg.user_public_key); @@ -757,7 +765,7 @@ fn adapt_output_for_reply( }); should_append_reply_params = false; - }, + } RawWasmOutput::OkV1 { ok, .. } => { output_result = SubMsgResult::Ok(SubMsgResponse { events: vec![], @@ -765,14 +773,26 @@ fn adapt_output_for_reply( }); should_append_reply_params = true; - }, - _ => return Ok(output) + } + _ => return Ok(output), } match &mut output { - RawWasmOutput::Err { internal_msg_id, internal_reply_enclave_sig, .. } | - RawWasmOutput::OkV010 { internal_msg_id, internal_reply_enclave_sig, .. } | - RawWasmOutput::OkV1 { internal_msg_id, internal_reply_enclave_sig, .. } => { + RawWasmOutput::Err { + internal_msg_id, + internal_reply_enclave_sig, + .. + } + | RawWasmOutput::OkV010 { + internal_msg_id, + internal_reply_enclave_sig, + .. + } + | RawWasmOutput::OkV1 { + internal_msg_id, + internal_reply_enclave_sig, + .. + } => { let (msg_id, callback_sig) = get_reply_info_for_output( output_result, reply_params, @@ -783,7 +803,7 @@ fn adapt_output_for_reply( *internal_msg_id = Some(msg_id); *internal_reply_enclave_sig = Some(callback_sig); - }, + } _ => {} } @@ -819,9 +839,7 @@ fn get_reply_info_for_output( EnclaveError::FailedToSerialize })?; - let sig = Binary::from( - create_callback_signature(sender_addr, &reply_json, &[]).as_slice(), - ); + let sig = Binary::from(create_callback_signature(sender_addr, &reply_json, &[]).as_slice()); trace!( "Generated internal callback signature for msg {:?} signature is: {:?}", @@ -865,7 +883,11 @@ fn encrypt_v010_wasm_msg( msg_to_pass.encrypt_in_place()?; *msg = Binary::from(msg_to_pass.to_vec().as_slice()); - *callback_sig = Some(create_callback_signature(contract_addr, &msg_to_pass.msg, send)); + *callback_sig = Some(create_callback_signature( + contract_addr, + &msg_to_pass.msg, + send, + )); } } @@ -881,16 +903,8 @@ fn attach_reply_headers_to_v1_wasm_msg( reply_params: &Option>, ) -> Result<(), EnclaveError> { match wasm_msg { - cw_types_v1::results::WasmMsg::Execute { - msg, - code_hash, - .. - } - | cw_types_v1::results::WasmMsg::Instantiate { - msg, - code_hash, - .. - } => { + cw_types_v1::results::WasmMsg::Execute { msg, code_hash, .. } + | cw_types_v1::results::WasmMsg::Instantiate { msg, code_hash, .. } => { // On cosmwasm v1, submessages execute contracts whose results are sent back to the original caller by using "Reply". // Such submessages should be encrypted, but they weren't initially meant to be sent back to the enclave as an input of another contract. // To support "sending back" behavior, the enclave expects every encrypted input to be prepended by the recipient's contract hash. diff --git a/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs b/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs index 1395993dc..3c7c488a0 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs @@ -268,7 +268,7 @@ impl Engine { .to_enclave_result()?; // let duration = start.elapsed(); // trace!("Time elapsed in environment.new_runtime is: {:?}", duration); - debug!("initialized runtime"); + trace!("initialized runtime"); // let start = Instant::now(); let module = self @@ -280,31 +280,31 @@ impl Engine { // "Time elapsed in environment.parse_module is: {:?}", // duration // ); - debug!("parsed module"); + trace!("parsed module"); // let start = Instant::now(); let mut instance = runtime.load_module(module).to_enclave_result()?; // let duration = start.elapsed(); // trace!("Time elapsed in runtime.load_module is: {:?}", duration); - debug!("created instance"); + trace!("created instance"); // let start = Instant::now(); gas::set_gas_limit(&instance, self.gas_limit)?; // let duration = start.elapsed(); // trace!("Time elapsed in set_gas_limit is: {:?}", duration); - debug!("set gas limit"); + trace!("set gas limit"); // let start = Instant::now(); Self::link_host_functions(&mut instance).to_enclave_result()?; // let duration = start.elapsed(); // trace!("Time elapsed in link_host_functions is: {:?}", duration); - debug!("linked functions"); + trace!("linked functions"); // let start = Instant::now(); let result = func(&mut instance, &mut self.context); // let duration = start.elapsed(); // trace!("Instance: elapsed time for running func is: {:?}", duration); - debug!("function returned {:?}", result); + trace!("function returned {:?}", result); self.used_gas = self .gas_limit @@ -400,26 +400,26 @@ impl Engine { let result = match api_version { CosmWasmApiVersion::V010 => { - let (init, args) = ( + let (migrate, args) = ( instance .find_function::<(u32, u32), u32>("migrate") .to_enclave_result()?, (env_ptr, msg_ptr), ); - init.call_with_context(context, args) + migrate.call_with_context(context, args) } CosmWasmApiVersion::V1 => { let msg_info_ptr = write_to_memory(instance, &msg_info_bytes)?; - let (init, args) = ( + let (migrate, args) = ( instance - .find_function::<(u32, u32, u32), u32>("migrate") + .find_function::<(u32, u32), u32>("migrate") .to_enclave_result()?, - (env_ptr, msg_info_ptr, msg_ptr), + (env_ptr, msg_ptr), ); // let start = Instant::now(); // let res = - init.call_with_context(context, args) + migrate.call_with_context(context, args) // let duration = start.elapsed(); // trace!("Time elapsed in call_with_context is: {:?}", duration); // res @@ -516,13 +516,13 @@ impl Engine { let api_version = self.get_api_version(); self.with_instance(|instance, context| { - debug!("starting handle"); + trace!("starting handle"); let (env_bytes, msg_info_bytes) = env.get_wasm_ptrs()?; let msg_ptr = write_to_memory(instance, &msg)?; - debug!("handle written msg"); + trace!("handle written msg"); let env_ptr = write_to_memory(instance, &env_bytes)?; - debug!("handle written env"); + trace!("handle written env"); let result = match api_version { CosmWasmApiVersion::V010 => { @@ -536,7 +536,6 @@ impl Engine { } CosmWasmApiVersion::V1 => { let export_name = HandleType::get_export_name(handle_type); - if handle_type == &HandleType::HANDLE_TYPE_EXECUTE { let msg_info_ptr = write_to_memory(instance, &msg_info_bytes)?; let (handle, args) = ( @@ -561,13 +560,13 @@ impl Engine { } }; - debug!("found handle"); + trace!("found handle"); let output_ptr = check_execution_result(instance, context, result)?; - debug!("called handle"); + trace!("called handle"); let output = read_from_memory(instance, output_ptr)?; - debug!("extracted handle output: {:?}", output); + trace!("extracted handle output: {:?}", output); Ok(output) }) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/wasm3/module_cache.rs b/cosmwasm/enclaves/shared/contract-engine/src/wasm3/module_cache.rs index 53b4f0ee9..39ddbea5f 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/wasm3/module_cache.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/wasm3/module_cache.rs @@ -47,21 +47,21 @@ pub fn create_module_instance( gas_costs: &WasmCosts, operation: ContractOperation, ) -> Result { - debug!("fetching module from cache"); + trace!("fetching module from cache"); let cache = MODULE_CACHE.read().unwrap(); // If the cache is disabled, don't try to use it and just compile the module. if cache.cap() == 0 { - debug!("cache is disabled, building module"); + trace!("cache is disabled, building module"); return analyze_module(contract_code, gas_costs, operation); } - debug!("cache is enabled"); + trace!("cache is enabled"); // Try to fetch a cached instance let mut code = None; let mut api_version = CosmWasmApiVersion::Invalid; let mut features = vec![]; - debug!("peeking in cache"); + trace!("peeking in cache"); let peek_result = cache.peek(&contract_code.hash()); if let Some(VersionedCode { code: cached_code, @@ -69,7 +69,7 @@ pub fn create_module_instance( features: cached_features, }) = peek_result { - debug!("found instance in cache!"); + trace!("found instance in cache!"); code = Some(cached_code.clone()); api_version = *cached_ver; features = cached_features.clone(); @@ -79,7 +79,7 @@ pub fn create_module_instance( // if we couldn't find the code in the cache, analyze it now if code.is_none() { - debug!("code not found in cache! analyzing now"); + trace!("code not found in cache! analyzing now"); let versioned_code = analyze_module(contract_code, gas_costs, operation)?; code = Some(versioned_code.code); api_version = versioned_code.version; @@ -87,23 +87,23 @@ pub fn create_module_instance( } // If we analyzed the code in the previous step, insert it to the LRU cache - debug!("updating cache"); + trace!("updating cache"); let mut cache = MODULE_CACHE.write().unwrap(); if let Some(code) = code.clone() { - debug!("storing code in cache"); + trace!("storing code in cache"); cache.put( contract_code.hash(), VersionedCode::new(code, api_version, features.clone()), ); } else { // Touch the cache to update the LRU value - debug!("updating LRU without storing anything"); + trace!("updating LRU without storing anything"); cache.get(&contract_code.hash()); } let code = code.unwrap(); - debug!("returning built instance"); + trace!("returning built instance"); Ok(VersionedCode::new(code, api_version, features)) } diff --git a/cosmwasm/enclaves/shared/cosmos-proto/src/cosmwasm/msg.rs b/cosmwasm/enclaves/shared/cosmos-proto/src/cosmwasm/msg.rs index 0e4864322..92db95e57 100644 --- a/cosmwasm/enclaves/shared/cosmos-proto/src/cosmwasm/msg.rs +++ b/cosmwasm/enclaves/shared/cosmos-proto/src/cosmwasm/msg.rs @@ -470,6 +470,7 @@ pub struct MsgInstantiateContract { pub init_msg: ::std::vec::Vec, pub init_funds: ::protobuf::RepeatedField, pub callback_sig: ::std::vec::Vec, + pub admin: ::std::vec::Vec, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -655,6 +656,32 @@ impl MsgInstantiateContract { pub fn take_callback_sig(&mut self) -> ::std::vec::Vec { ::std::mem::replace(&mut self.callback_sig, ::std::vec::Vec::new()) } + + // bytes admin = 8; + + + pub fn get_admin(&self) -> &[u8] { + &self.admin + } + pub fn clear_admin(&mut self) { + self.admin.clear(); + } + + // Param is passed by value, moved + pub fn set_admin(&mut self, v: ::std::vec::Vec) { + self.admin = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_admin(&mut self) -> &mut ::std::vec::Vec { + &mut self.admin + } + + // Take field + pub fn take_admin(&mut self) -> ::std::vec::Vec { + ::std::mem::replace(&mut self.admin, ::std::vec::Vec::new()) + } } impl ::protobuf::Message for MsgInstantiateContract { @@ -696,6 +723,9 @@ impl ::protobuf::Message for MsgInstantiateContract { 7 => { ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.callback_sig)?; }, + 8 => { + ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.admin)?; + }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; }, @@ -730,6 +760,9 @@ impl ::protobuf::Message for MsgInstantiateContract { if !self.callback_sig.is_empty() { my_size += ::protobuf::rt::bytes_size(7, &self.callback_sig); } + if !self.admin.is_empty() { + my_size += ::protobuf::rt::bytes_size(8, &self.admin); + } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -759,6 +792,9 @@ impl ::protobuf::Message for MsgInstantiateContract { if !self.callback_sig.is_empty() { os.write_bytes(7, &self.callback_sig)?; } + if !self.admin.is_empty() { + os.write_bytes(8, &self.admin)?; + } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -832,6 +868,11 @@ impl ::protobuf::Message for MsgInstantiateContract { |m: &MsgInstantiateContract| { &m.callback_sig }, |m: &mut MsgInstantiateContract| { &mut m.callback_sig }, )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( + "admin", + |m: &MsgInstantiateContract| { &m.admin }, + |m: &mut MsgInstantiateContract| { &mut m.admin }, + )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "MsgInstantiateContract", fields, @@ -855,6 +896,7 @@ impl ::protobuf::Clear for MsgInstantiateContract { self.init_msg.clear(); self.init_funds.clear(); self.callback_sig.clear(); + self.admin.clear(); self.unknown_fields.clear(); } } @@ -1607,6 +1649,1119 @@ impl ::protobuf::reflect::ProtobufValue for MsgExecuteContractResponse { } } +#[derive(PartialEq,Clone,Default)] +pub struct MsgMigrateContract { + // message fields + pub sender: ::std::string::String, + pub contract: ::std::string::String, + pub code_id: u64, + pub msg: ::std::vec::Vec, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a MsgMigrateContract { + fn default() -> &'a MsgMigrateContract { + ::default_instance() + } +} + +impl MsgMigrateContract { + pub fn new() -> MsgMigrateContract { + ::std::default::Default::default() + } + + // string sender = 1; + + + pub fn get_sender(&self) -> &str { + &self.sender + } + pub fn clear_sender(&mut self) { + self.sender.clear(); + } + + // Param is passed by value, moved + pub fn set_sender(&mut self, v: ::std::string::String) { + self.sender = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_sender(&mut self) -> &mut ::std::string::String { + &mut self.sender + } + + // Take field + pub fn take_sender(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.sender, ::std::string::String::new()) + } + + // string contract = 2; + + + pub fn get_contract(&self) -> &str { + &self.contract + } + pub fn clear_contract(&mut self) { + self.contract.clear(); + } + + // Param is passed by value, moved + pub fn set_contract(&mut self, v: ::std::string::String) { + self.contract = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_contract(&mut self) -> &mut ::std::string::String { + &mut self.contract + } + + // Take field + pub fn take_contract(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.contract, ::std::string::String::new()) + } + + // uint64 code_id = 3; + + + pub fn get_code_id(&self) -> u64 { + self.code_id + } + pub fn clear_code_id(&mut self) { + self.code_id = 0; + } + + // Param is passed by value, moved + pub fn set_code_id(&mut self, v: u64) { + self.code_id = v; + } + + // bytes msg = 4; + + + pub fn get_msg(&self) -> &[u8] { + &self.msg + } + pub fn clear_msg(&mut self) { + self.msg.clear(); + } + + // Param is passed by value, moved + pub fn set_msg(&mut self, v: ::std::vec::Vec) { + self.msg = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_msg(&mut self) -> &mut ::std::vec::Vec { + &mut self.msg + } + + // Take field + pub fn take_msg(&mut self) -> ::std::vec::Vec { + ::std::mem::replace(&mut self.msg, ::std::vec::Vec::new()) + } +} + +impl ::protobuf::Message for MsgMigrateContract { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.sender)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.contract)?; + }, + 3 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_uint64()?; + self.code_id = tmp; + }, + 4 => { + ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.msg)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.sender.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.sender); + } + if !self.contract.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.contract); + } + if self.code_id != 0 { + my_size += ::protobuf::rt::value_size(3, self.code_id, ::protobuf::wire_format::WireTypeVarint); + } + if !self.msg.is_empty() { + my_size += ::protobuf::rt::bytes_size(4, &self.msg); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.sender.is_empty() { + os.write_string(1, &self.sender)?; + } + if !self.contract.is_empty() { + os.write_string(2, &self.contract)?; + } + if self.code_id != 0 { + os.write_uint64(3, self.code_id)?; + } + if !self.msg.is_empty() { + os.write_bytes(4, &self.msg)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> MsgMigrateContract { + MsgMigrateContract::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "sender", + |m: &MsgMigrateContract| { &m.sender }, + |m: &mut MsgMigrateContract| { &mut m.sender }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "contract", + |m: &MsgMigrateContract| { &m.contract }, + |m: &mut MsgMigrateContract| { &mut m.contract }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeUint64>( + "code_id", + |m: &MsgMigrateContract| { &m.code_id }, + |m: &mut MsgMigrateContract| { &mut m.code_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( + "msg", + |m: &MsgMigrateContract| { &m.msg }, + |m: &mut MsgMigrateContract| { &mut m.msg }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MsgMigrateContract", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MsgMigrateContract { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MsgMigrateContract::new) + } +} + +impl ::protobuf::Clear for MsgMigrateContract { + fn clear(&mut self) { + self.sender.clear(); + self.contract.clear(); + self.code_id = 0; + self.msg.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MsgMigrateContract { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MsgMigrateContract { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct MsgMigrateContractResponse { + // message fields + pub data: ::std::vec::Vec, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a MsgMigrateContractResponse { + fn default() -> &'a MsgMigrateContractResponse { + ::default_instance() + } +} + +impl MsgMigrateContractResponse { + pub fn new() -> MsgMigrateContractResponse { + ::std::default::Default::default() + } + + // bytes data = 1; + + + pub fn get_data(&self) -> &[u8] { + &self.data + } + pub fn clear_data(&mut self) { + self.data.clear(); + } + + // Param is passed by value, moved + pub fn set_data(&mut self, v: ::std::vec::Vec) { + self.data = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_data(&mut self) -> &mut ::std::vec::Vec { + &mut self.data + } + + // Take field + pub fn take_data(&mut self) -> ::std::vec::Vec { + ::std::mem::replace(&mut self.data, ::std::vec::Vec::new()) + } +} + +impl ::protobuf::Message for MsgMigrateContractResponse { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.data)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.data.is_empty() { + my_size += ::protobuf::rt::bytes_size(1, &self.data); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.data.is_empty() { + os.write_bytes(1, &self.data)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> MsgMigrateContractResponse { + MsgMigrateContractResponse::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( + "data", + |m: &MsgMigrateContractResponse| { &m.data }, + |m: &mut MsgMigrateContractResponse| { &mut m.data }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MsgMigrateContractResponse", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MsgMigrateContractResponse { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MsgMigrateContractResponse::new) + } +} + +impl ::protobuf::Clear for MsgMigrateContractResponse { + fn clear(&mut self) { + self.data.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MsgMigrateContractResponse { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MsgMigrateContractResponse { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct MsgUpdateAdmin { + // message fields + pub sender: ::std::string::String, + pub new_admin: ::std::string::String, + pub contract: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a MsgUpdateAdmin { + fn default() -> &'a MsgUpdateAdmin { + ::default_instance() + } +} + +impl MsgUpdateAdmin { + pub fn new() -> MsgUpdateAdmin { + ::std::default::Default::default() + } + + // string sender = 1; + + + pub fn get_sender(&self) -> &str { + &self.sender + } + pub fn clear_sender(&mut self) { + self.sender.clear(); + } + + // Param is passed by value, moved + pub fn set_sender(&mut self, v: ::std::string::String) { + self.sender = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_sender(&mut self) -> &mut ::std::string::String { + &mut self.sender + } + + // Take field + pub fn take_sender(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.sender, ::std::string::String::new()) + } + + // string new_admin = 2; + + + pub fn get_new_admin(&self) -> &str { + &self.new_admin + } + pub fn clear_new_admin(&mut self) { + self.new_admin.clear(); + } + + // Param is passed by value, moved + pub fn set_new_admin(&mut self, v: ::std::string::String) { + self.new_admin = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_new_admin(&mut self) -> &mut ::std::string::String { + &mut self.new_admin + } + + // Take field + pub fn take_new_admin(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.new_admin, ::std::string::String::new()) + } + + // string contract = 3; + + + pub fn get_contract(&self) -> &str { + &self.contract + } + pub fn clear_contract(&mut self) { + self.contract.clear(); + } + + // Param is passed by value, moved + pub fn set_contract(&mut self, v: ::std::string::String) { + self.contract = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_contract(&mut self) -> &mut ::std::string::String { + &mut self.contract + } + + // Take field + pub fn take_contract(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.contract, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for MsgUpdateAdmin { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.sender)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.new_admin)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.contract)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.sender.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.sender); + } + if !self.new_admin.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.new_admin); + } + if !self.contract.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.contract); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.sender.is_empty() { + os.write_string(1, &self.sender)?; + } + if !self.new_admin.is_empty() { + os.write_string(2, &self.new_admin)?; + } + if !self.contract.is_empty() { + os.write_string(3, &self.contract)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> MsgUpdateAdmin { + MsgUpdateAdmin::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "sender", + |m: &MsgUpdateAdmin| { &m.sender }, + |m: &mut MsgUpdateAdmin| { &mut m.sender }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "new_admin", + |m: &MsgUpdateAdmin| { &m.new_admin }, + |m: &mut MsgUpdateAdmin| { &mut m.new_admin }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "contract", + |m: &MsgUpdateAdmin| { &m.contract }, + |m: &mut MsgUpdateAdmin| { &mut m.contract }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MsgUpdateAdmin", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MsgUpdateAdmin { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MsgUpdateAdmin::new) + } +} + +impl ::protobuf::Clear for MsgUpdateAdmin { + fn clear(&mut self) { + self.sender.clear(); + self.new_admin.clear(); + self.contract.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MsgUpdateAdmin { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MsgUpdateAdmin { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct MsgUpdateAdminResponse { + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a MsgUpdateAdminResponse { + fn default() -> &'a MsgUpdateAdminResponse { + ::default_instance() + } +} + +impl MsgUpdateAdminResponse { + pub fn new() -> MsgUpdateAdminResponse { + ::std::default::Default::default() + } +} + +impl ::protobuf::Message for MsgUpdateAdminResponse { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> MsgUpdateAdminResponse { + MsgUpdateAdminResponse::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let fields = ::std::vec::Vec::new(); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MsgUpdateAdminResponse", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MsgUpdateAdminResponse { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MsgUpdateAdminResponse::new) + } +} + +impl ::protobuf::Clear for MsgUpdateAdminResponse { + fn clear(&mut self) { + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MsgUpdateAdminResponse { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MsgUpdateAdminResponse { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct MsgClearAdmin { + // message fields + pub sender: ::std::string::String, + pub contract: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a MsgClearAdmin { + fn default() -> &'a MsgClearAdmin { + ::default_instance() + } +} + +impl MsgClearAdmin { + pub fn new() -> MsgClearAdmin { + ::std::default::Default::default() + } + + // string sender = 1; + + + pub fn get_sender(&self) -> &str { + &self.sender + } + pub fn clear_sender(&mut self) { + self.sender.clear(); + } + + // Param is passed by value, moved + pub fn set_sender(&mut self, v: ::std::string::String) { + self.sender = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_sender(&mut self) -> &mut ::std::string::String { + &mut self.sender + } + + // Take field + pub fn take_sender(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.sender, ::std::string::String::new()) + } + + // string contract = 3; + + + pub fn get_contract(&self) -> &str { + &self.contract + } + pub fn clear_contract(&mut self) { + self.contract.clear(); + } + + // Param is passed by value, moved + pub fn set_contract(&mut self, v: ::std::string::String) { + self.contract = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_contract(&mut self) -> &mut ::std::string::String { + &mut self.contract + } + + // Take field + pub fn take_contract(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.contract, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for MsgClearAdmin { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.sender)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.contract)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.sender.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.sender); + } + if !self.contract.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.contract); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.sender.is_empty() { + os.write_string(1, &self.sender)?; + } + if !self.contract.is_empty() { + os.write_string(3, &self.contract)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> MsgClearAdmin { + MsgClearAdmin::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "sender", + |m: &MsgClearAdmin| { &m.sender }, + |m: &mut MsgClearAdmin| { &mut m.sender }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "contract", + |m: &MsgClearAdmin| { &m.contract }, + |m: &mut MsgClearAdmin| { &mut m.contract }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MsgClearAdmin", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MsgClearAdmin { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MsgClearAdmin::new) + } +} + +impl ::protobuf::Clear for MsgClearAdmin { + fn clear(&mut self) { + self.sender.clear(); + self.contract.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MsgClearAdmin { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MsgClearAdmin { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct MsgClearAdminResponse { + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a MsgClearAdminResponse { + fn default() -> &'a MsgClearAdminResponse { + ::default_instance() + } +} + +impl MsgClearAdminResponse { + pub fn new() -> MsgClearAdminResponse { + ::std::default::Default::default() + } +} + +impl ::protobuf::Message for MsgClearAdminResponse { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> MsgClearAdminResponse { + MsgClearAdminResponse::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let fields = ::std::vec::Vec::new(); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MsgClearAdminResponse", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MsgClearAdminResponse { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MsgClearAdminResponse::new) + } +} + +impl ::protobuf::Clear for MsgClearAdminResponse { + fn clear(&mut self) { + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MsgClearAdminResponse { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MsgClearAdminResponse { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + static file_descriptor_proto_data: &'static [u8] = b"\ \n\x20secret/compute/v1beta1/msg.proto\x12\x16secret.compute.v1beta1\x1a\ \x14gogoproto/gogo.proto\x1a\x1ecosmos/base/v1beta1/coin.proto\"\xc9\x01\ @@ -1616,7 +2771,7 @@ static file_descriptor_proto_data: &'static [u8] = b"\ SMByteCode\x12\x16\n\x06source\x18\x03\x20\x01(\tR\x06source\x12\x18\n\ \x07builder\x18\x04\x20\x01(\tR\x07builder:\x04\x88\xa0\x1f\0\";\n\x14Ms\ gStoreCodeResponse\x12#\n\x07code_id\x18\x01\x20\x01(\x04R\x06codeIdB\n\ - \xe2\xde\x1f\x06CodeID\"\x8d\x03\n\x16MsgInstantiateContract\x12I\n\x06s\ + \xe2\xde\x1f\x06CodeID\"\xd6\x03\n\x16MsgInstantiateContract\x12I\n\x06s\ ender\x18\x01\x20\x01(\x0cR\x06senderB1\xfa\xde\x1f-github.com/cosmos/co\ smos-sdk/types.AccAddress\x12,\n\x12callback_code_hash\x18\x02\x20\x01(\ \tR\x10callbackCodeHash\x12#\n\x07code_id\x18\x03\x20\x01(\x04R\x06codeI\ @@ -1625,25 +2780,39 @@ static file_descriptor_proto_data: &'static [u8] = b"\ unds\x18\x06\x20\x03(\x0b2\x19.cosmos.base.v1beta1.CoinR\tinitFundsB0\ \xaa\xdf\x1f(github.com/cosmos/cosmos-sdk/types.Coins\xc8\xde\x1f\0\x122\ \n\x0ccallback_sig\x18\x07\x20\x01(\x0cR\x0bcallbackSigB\x0f\xe2\xde\x1f\ - \x0bCallbackSig:\x04\x88\xa0\x1f\0\"N\n\x1eMsgInstantiateContractRespons\ - e\x12\x18\n\x07address\x18\x01\x20\x01(\tR\x07address\x12\x12\n\x04data\ - \x18\x02\x20\x01(\x0cR\x04data\"\x94\x03\n\x12MsgExecuteContract\x12I\n\ - \x06sender\x18\x01\x20\x01(\x0cR\x06senderB1\xfa\xde\x1f-github.com/cosm\ - os/cosmos-sdk/types.AccAddress\x12M\n\x08contract\x18\x02\x20\x01(\x0cR\ - \x08contractB1\xfa\xde\x1f-github.com/cosmos/cosmos-sdk/types.AccAddress\ - \x12\x10\n\x03msg\x18\x03\x20\x01(\x0cR\x03msg\x12,\n\x12callback_code_h\ - ash\x18\x04\x20\x01(\tR\x10callbackCodeHash\x12j\n\nsent_funds\x18\x05\ - \x20\x03(\x0b2\x19.cosmos.base.v1beta1.CoinR\tsentFundsB0\xaa\xdf\x1f(gi\ - thub.com/cosmos/cosmos-sdk/types.Coins\xc8\xde\x1f\0\x122\n\x0ccallback_\ - sig\x18\x06\x20\x01(\x0cR\x0bcallbackSigB\x0f\xe2\xde\x1f\x0bCallbackSig\ - :\x04\x88\xa0\x1f\0\"0\n\x1aMsgExecuteContractResponse\x12\x12\n\x04data\ - \x18\x01\x20\x01(\x0cR\x04data2\xd8\x02\n\x03Msg\x12_\n\tStoreCode\x12$.\ - secret.compute.v1beta1.MsgStoreCode\x1a,.secret.compute.v1beta1.MsgStore\ - CodeResponse\x12}\n\x13InstantiateContract\x12..secret.compute.v1beta1.M\ - sgInstantiateContract\x1a6.secret.compute.v1beta1.MsgInstantiateContract\ - Response\x12q\n\x0fExecuteContract\x12*.secret.compute.v1beta1.MsgExecut\ - eContract\x1a2.secret.compute.v1beta1.MsgExecuteContractResponseB = ::protobuf::rt::LazyV2::INIT; diff --git a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs index 2dec95068..d53ab2252 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs @@ -302,6 +302,11 @@ pub enum StdCosmWasmMsg { label: String, callback_sig: Option>, }, + Migrate { + sender: HumanAddr, + code_id: String, + msg: String, + }, #[serde(other, deserialize_with = "deserialize_ignore_any")] Other, } @@ -315,6 +320,21 @@ pub fn deserialize_ignore_any<'de, D: serde::Deserializer<'de>, T: Default>( impl StdCosmWasmMsg { pub fn into_cosmwasm_msg(self) -> Result { match self { + Self::Migrate { sender, msg, .. } => { + let sender = CanonicalAddr::from_human(&sender).map_err(|err| { + warn!("failed to turn human addr to canonical addr when parsing CosmWasmMsg: {:?}", err); + EnclaveError::FailedToDeserialize + })?; + let msg = Binary::from_base64(&msg).map_err(|err| { + warn!( + "failed to parse base64 msg when parsing CosmWasmMsg: {:?}", + err + ); + EnclaveError::FailedToDeserialize + })?; + let msg = msg.0; + Ok(CosmWasmMsg::Migrate { sender, msg }) + } Self::Execute { sender, contract, @@ -391,6 +411,10 @@ pub enum CosmWasmMsg { label: String, callback_sig: Option>, }, + Migrate { + sender: CanonicalAddr, + msg: Vec, + }, Other, } @@ -398,6 +422,7 @@ impl CosmWasmMsg { pub fn from_bytes(bytes: &[u8]) -> Result { Self::try_parse_execute(bytes) .or_else(|_| Self::try_parse_instantiate(bytes)) + .or_else(|_| Self::try_parse_migrate(bytes)) .or_else(|_| { warn!( "got an error while trying to deserialize cosmwasm message bytes from protobuf: {}", @@ -406,6 +431,26 @@ impl CosmWasmMsg { Ok(CosmWasmMsg::Other) }) } + fn try_parse_migrate(bytes: &[u8]) -> Result { + use proto::cosmwasm::msg::MsgMigrateContract; + + let raw_msg = MsgMigrateContract::parse_from_bytes(bytes) + .map_err(|_| EnclaveError::FailedToDeserialize)?; + + trace!( + "try_parse_instantiate sender: len={} val={:?}", + raw_msg.sender.len(), + raw_msg.sender + ); + + let sender = CanonicalAddr::from_human(&HumanAddr(raw_msg.sender)) + .map_err(|_| EnclaveError::FailedToDeserialize)?; + + Ok(CosmWasmMsg::Migrate { + sender, + msg: raw_msg.msg, + }) + } fn try_parse_instantiate(bytes: &[u8]) -> Result { use proto::cosmwasm::msg::MsgInstantiateContract; @@ -496,9 +541,9 @@ impl CosmWasmMsg { pub fn sender(&self) -> Option<&CanonicalAddr> { match self { - CosmWasmMsg::Execute { sender, .. } | CosmWasmMsg::Instantiate { sender, .. } => { - Some(sender) - } + CosmWasmMsg::Execute { sender, .. } + | CosmWasmMsg::Instantiate { sender, .. } + | CosmWasmMsg::Migrate { sender, .. } => Some(sender), CosmWasmMsg::Other => None, } } diff --git a/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs b/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs index 46c07de71..406775c8a 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs @@ -125,7 +125,9 @@ impl BaseEnv { contract: v010types::ContractInfo { address: self.0.contract.address, }, - contract_key: self.0.contract_key, + // to maintain compatability with v010 we just return none here - no contract would care + // about this anyway + contract_key: None, contract_code_hash: self.0.contract_code_hash, transaction: None, }, diff --git a/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/types.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/types.rs index 045e7f30c..0c1c8007b 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/types.rs @@ -101,7 +101,7 @@ pub struct ContractKey { #[derive(Serialize, Deserialize, Clone, Default, Debug, PartialEq)] pub struct ContractKeyWithProof { pub key: String, - pub proof: [u8; 32], + pub proof: String, } impl ContractKeyWithProof { @@ -112,6 +112,14 @@ impl ContractKeyWithProof { output } + + pub fn decode_proof(&self) -> [u8; 32] { + let mut output = [0u8; 32]; + let decoded = base64::decode(&self.proof).unwrap(); + output.copy_from_slice(&decoded); + + output + } } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] diff --git a/go-cosmwasm/api/lib.go b/go-cosmwasm/api/lib.go index 9b0a7cd20..01409f0d7 100644 --- a/go-cosmwasm/api/lib.go +++ b/go-cosmwasm/api/lib.go @@ -188,7 +188,7 @@ func Migrate( defer freeAfterSend(adminBuffer) adminProofBuffer := sendSlice(adminProof) - defer freeAfterSend(adminBuffer) + defer freeAfterSend(adminProofBuffer) //// This is done in order to ensure that goroutines don't //// swap threads between recursive calls to the enclave. diff --git a/go-cosmwasm/types/env.go b/go-cosmwasm/types/env.go index ed8191ab6..68205b225 100644 --- a/go-cosmwasm/types/env.go +++ b/go-cosmwasm/types/env.go @@ -17,13 +17,13 @@ type Env struct { } type ContractKey struct { - Key []byte `json:"key"` - Original ContractKeyWithProof `json:"original,omitempty"` + Key []byte `json:"key"` + Original *ContractKeyWithProof `json:"original,omitempty"` } type ContractKeyWithProof struct { - Key []byte `json:"key"` - Proof []byte `json:"proof"` + Key []byte `json:"key,omitempty"` + Proof []byte `json:"proof,omitempty"` } type TransactionInfo struct { diff --git a/proto/secret/compute/v1beta1/msg.proto b/proto/secret/compute/v1beta1/msg.proto index cb8dd08fe..bbc042256 100644 --- a/proto/secret/compute/v1beta1/msg.proto +++ b/proto/secret/compute/v1beta1/msg.proto @@ -15,6 +15,7 @@ service Msg { // Execute submits the given message data to a smart contract rpc ExecuteContract(MsgExecuteContract) returns (MsgExecuteContractResponse); + rpc MigrateContract(MsgMigrateContract) returns (MsgMigrateContractResponse); } message MsgStoreCode { diff --git a/x/compute/internal/keeper/distribution_test.go b/x/compute/internal/keeper/distribution_test.go index aa29fb43d..aaa8627fa 100644 --- a/x/compute/internal/keeper/distribution_test.go +++ b/x/compute/internal/keeper/distribution_test.go @@ -80,7 +80,7 @@ func TestDistributionRewards(t *testing.T) { require.NoError(t, err) ctx = PrepareInitSignedTx(t, keeper, ctx, creator, creatorPrivKey, initBz, govId, nil) - govAddr, _, err := keeper.Instantiate(ctx, govId, creator, nil, initBz, "gidi gov", nil, nil) + govAddr, _, err := keeper.Instantiate(ctx, govId, creator, creator, initBz, "gidi gov", nil, nil) require.NoError(t, err) require.NotEmpty(t, govAddr) diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index 784719f6e..eb5a08da0 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -376,6 +376,10 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator sdk.AccAddre return nil, nil, sdkerrors.Wrap(types.ErrAccountExists, existingAcct.GetAddress().String()) } + if admin == nil { + admin = creator + } + // deposit initial contract funds if !deposit.IsZero() { if k.bankKeeper.BlockedAddr(creator) { @@ -422,6 +426,9 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator sdk.AccAddre response, key, adminProof, gasUsed, err := k.wasmer.Instantiate(codeInfo.CodeHash, env, initMsg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, verificationInfo, admin) consumeGas(ctx, gasUsed) + println("Got admin proof: *******************************", hex.EncodeToString(adminProof)) + println("Got new key: *******************************", hex.EncodeToString(key)) + if err != nil { switch res := response.(type) { //nolint:gocritic case v1wasmTypes.DataWithInternalReplyInfo: @@ -444,8 +451,15 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator sdk.AccAddre createdAt := types.NewAbsoluteTxPosition(ctx) contractInfo := types.NewContractInfo(codeID, creator, admin, adminProof, label, createdAt) - k.storeContractInfo(ctx, contractAddress, &contractInfo) - store.Set(types.GetContractEnclaveKey(contractAddress), key) + historyEntry := contractInfo.InitialHistory(initMsg) + k.addToContractCodeSecondaryIndex(ctx, contractAddress, historyEntry) + //k.addToContractCreatorSecondaryIndex(ctx, creator, historyEntry.Updated, contractAddress) + k.appendToContractHistory(ctx, contractAddress, historyEntry) + + k.setContractInfo(ctx, contractAddress, &contractInfo) + k.SetContractKey(ctx, contractAddress, &types.ContractKey{ + Key: key, + }) store.Set(types.GetContractLabelPrefix(label), contractAddress) subMessages, err := V010MsgsToV1SubMsgs(contractAddress.String(), res.Messages) @@ -484,9 +498,16 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator sdk.AccAddre sdk.NewAttribute(types.AttributeKeyCodeID, strconv.FormatUint(codeID, 10)), )) + historyEntry := contractInfo.InitialHistory(initMsg) + k.addToContractCodeSecondaryIndex(ctx, contractAddress, historyEntry) + //k.addToContractCreatorSecondaryIndex(ctx, creator, historyEntry.Updated, contractAddress) + k.appendToContractHistory(ctx, contractAddress, historyEntry) + // persist instance - k.storeContractInfo(ctx, contractAddress, &contractInfo) - store.Set(types.GetContractEnclaveKey(contractAddress), key) + k.setContractInfo(ctx, contractAddress, &contractInfo) + k.SetContractKey(ctx, contractAddress, &types.ContractKey{ + Key: key, + }) store.Set(types.GetContractLabelPrefix(label), contractAddress) data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res.Messages, res.Attributes, res.Events, res.Data, initMsg, verificationInfo, wasmTypes.CosmosMsgVersionV1) @@ -547,6 +568,13 @@ func (k Keeper) Execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller return nil, err } + println("Running with contract key: ******************************* ", hex.EncodeToString(contractKey.Key)) + + if contractKey.Original != nil { + println("Running with OG contract key: ******************************* ", hex.EncodeToString(contractKey.Original.Key)) + println("Running with OG Proof: ******************************* ", hex.EncodeToString(contractKey.Original.Proof)) + } + env := types.NewEnv(ctx, caller, coins, contractAddress, &contractKey, random) // prepare querier @@ -1200,6 +1228,9 @@ func (k Keeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller response, newContractKey, proof, gasUsed, err := k.wasmer.Migrate(newCodeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, gasMeter(ctx), gas, verificationInfo, admin, adminProof) consumeGas(ctx, gasUsed) + println("Got admin proof: *******************************", hex.EncodeToString(proof)) + println("Got new key: *******************************", hex.EncodeToString(newContractKey)) + // update contract key with new one k.SetContractKey(ctx, contractAddress, &types.ContractKey{ Key: newContractKey, @@ -1228,7 +1259,7 @@ func (k Keeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller historyEntry := contractInfo.AddMigration(ctx, newCodeID, msg) k.appendToContractHistory(ctx, contractAddress, historyEntry) k.addToContractCodeSecondaryIndex(ctx, contractAddress, historyEntry) - k.storeContractInfo(ctx, contractAddress, &contractInfo) + k.setContractInfo(ctx, contractAddress, &contractInfo) ctx.EventManager().EmitEvent(sdk.NewEvent( types.EventTypeMigrate, @@ -1251,8 +1282,9 @@ func (k Keeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller return data, nil case *v1wasmTypes.Response: ctx.EventManager().EmitEvent(sdk.NewEvent( - types.EventTypeExecute, + types.EventTypeMigrate, sdk.NewAttribute(types.AttributeKeyContractAddr, contractAddress.String()), + sdk.NewAttribute(types.AttributeKeyCodeID, strconv.FormatUint(newCodeID, 10)), )) data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res.Messages, res.Attributes, res.Events, res.Data, msg, verificationInfo, wasmTypes.CosmosMsgVersionV1) @@ -1325,12 +1357,6 @@ func (k Keeper) addToContractCodeSecondaryIndex(ctx sdk.Context, contractAddress store.Set(types.GetContractByCreatedSecondaryIndexKey(contractAddress, entry), []byte{}) } -// storeContractInfo persists the ContractInfo. No secondary index updated here. -func (k Keeper) storeContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress, contract *types.ContractInfo) { - store := ctx.KVStore(k.storeKey) - store.Set(types.GetContractAddressKey(contractAddress), k.cdc.MustMarshal(contract)) -} - func (k Keeper) GetStoreKey() sdk.StoreKey { return k.storeKey } diff --git a/x/compute/internal/keeper/param_verification_test.go b/x/compute/internal/keeper/param_verification_test.go index 49da066fc..50d4cf0ba 100644 --- a/x/compute/internal/keeper/param_verification_test.go +++ b/x/compute/internal/keeper/param_verification_test.go @@ -240,7 +240,7 @@ func TestMultipleSigners(t *testing.T) { []sdk.AccAddress{walletA, walletB}, []crypto.PrivKey{privKeyA, privKeyB}, []sdk.Msg{&sdkMsgA, &sdkMsgB}, codeID, ) - contractAddressA, _, err := keeper.Instantiate(ctx, codeID, walletA /* nil,*/, initMsgBz, "demo contract 1", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) + contractAddressA, _, err := keeper.Instantiate(ctx, codeID, walletA, nil, initMsgBz, "demo contract 1", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) if err != nil { err = extractInnerError(t, err, nonce, true, false) } @@ -258,7 +258,7 @@ func TestMultipleSigners(t *testing.T) { wasmEvents, ) - contractAddressB, _, err := keeper.Instantiate(ctx, codeID, walletB /* nil,*/, initMsgBz, "demo contract 2", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) + contractAddressB, _, err := keeper.Instantiate(ctx, codeID, walletB, nil, initMsgBz, "demo contract 2", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) if err != nil { err = extractInnerError(t, err, nonce, false, false) } @@ -301,7 +301,7 @@ func TestWrongSigner(t *testing.T) { ctx = prepareInitSignedTxMultipleMsgs(t, keeper, ctx, []sdk.AccAddress{walletB}, []crypto.PrivKey{privKeyB}, []sdk.Msg{&sdkMsgA}, codeID) - _, _, err = keeper.Instantiate(ctx, codeID, walletA /* nil,*/, initMsgBz, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) + _, _, err = keeper.Instantiate(ctx, codeID, walletA, nil, initMsgBz, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) if err != nil { err = extractInnerError(t, err, nonce, false, false) } @@ -330,7 +330,7 @@ func TestMultiSig(t *testing.T) { _, _, multisigAddr := multisigTxCreator(t, &ctx, keeper, i+1, j+1, i+1, &sdkMsg) - contractAddressA, _, err := keeper.Instantiate(ctx, codeID, multisigAddr.address, initMsgBz, label, sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) + contractAddressA, _, err := keeper.Instantiate(ctx, codeID, multisigAddr.address, nil, initMsgBz, label, sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) if err != nil { err = extractInnerError(t, err, nonce, false, false) } @@ -381,7 +381,7 @@ func TestMultiSigThreshold(t *testing.T) { _, _, multisigAddr := multisigTxCreator(t, &ctx, keeper, i+1, j+1, j+1, &sdkMsg) - contractAddressA, _, err := keeper.Instantiate(ctx, codeID, multisigAddr.address /* nil,*/, initMsgBz, label, sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) + contractAddressA, _, err := keeper.Instantiate(ctx, codeID, multisigAddr.address, nil, initMsgBz, label, sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) if err != nil { err = extractInnerError(t, err, nonce, true, false) } @@ -429,7 +429,7 @@ func TestMultiSigThresholdNotMet(t *testing.T) { _, _, multisigAddr := multisigTxCreator(t, &ctx, keeper, 3, 2, 1, &sdkMsg) - _, _, err = keeper.Instantiate(ctx, codeID, multisigAddr.address /* nil,*/, initMsgBz, "demo contract 1", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) + _, _, err = keeper.Instantiate(ctx, codeID, multisigAddr.address, nil, initMsgBz, "demo contract 1", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) if err != nil { err = extractInnerError(t, err, nonce, false, false) } @@ -625,7 +625,7 @@ func TestMultiSigInMultiSig(t *testing.T) { ctx, codeID, multimultisigAccount.address, - /* nil, */ + nil, initMsgBz, "demo contract 1", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), @@ -729,7 +729,7 @@ func TestMultiSigInMultiSigDifferentOrder(t *testing.T) { ctx, codeID, multimultisigAccount.address, - /* nil, */ + nil, initMsgBz, "demo contract 1", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), @@ -793,7 +793,7 @@ func TestInvalidKeyType(t *testing.T) { ctx = prepareInitSignedTxMultipleMsgs(t, keeper, ctx, []sdk.AccAddress{edAddr}, []crypto.PrivKey{edKey}, []sdk.Msg{&sdkMsg}, codeID) - _, _, err = keeper.Instantiate(ctx, codeID, edAddr /* nil,*/, initMsgBz, "demo contract 1", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) + _, _, err = keeper.Instantiate(ctx, codeID, edAddr, nil, initMsgBz, "demo contract 1", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) require.Contains(t, err.Error(), "failed to deserialize data") } @@ -876,7 +876,7 @@ func TestInvalidKeyTypeInMultisig(t *testing.T) { ctx, codeID, sdk.AccAddress(multisigPubkey.address), - /* nil, */ + nil, initMsgBz, "demo contract 1", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), @@ -902,7 +902,7 @@ func TestWrongFundsNoFunds(t *testing.T) { ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privKeyA, initMsgBz, codeID, nil) - _, _, err = keeper.Instantiate(ctx, codeID, walletA /* nil,*/, initMsgBz, "demo contract 1", sdk.NewCoins(sdk.NewInt64Coin("denom", 1000)), nil) + _, _, err = keeper.Instantiate(ctx, codeID, walletA, nil, initMsgBz, "demo contract 1", sdk.NewCoins(sdk.NewInt64Coin("denom", 1000)), nil) if err != nil { err = extractInnerError(t, err, nonce, false, false) } @@ -926,7 +926,7 @@ func TestWrongFundsSomeFunds(t *testing.T) { ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privKeyA, initMsgBz, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 200))) - _, _, err = keeper.Instantiate(ctx, codeID, walletA /* nil,*/, initMsgBz, "demo contract 1", sdk.NewCoins(sdk.NewInt64Coin("denom", 1000)), nil) + _, _, err = keeper.Instantiate(ctx, codeID, walletA, nil, initMsgBz, "demo contract 1", sdk.NewCoins(sdk.NewInt64Coin("denom", 1000)), nil) if err != nil { err = extractInnerError(t, err, nonce, false, false) } @@ -960,7 +960,7 @@ func TestWrongMessage(t *testing.T) { ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privKeyA, initMsgBz, codeID, nil) - _, _, err = keeper.Instantiate(ctx, codeID, walletA /* nil, */, notTheRealMsgBz, "demo contract 1", sdk.NewCoins(sdk.NewInt64Coin("denom", 1000)), nil) + _, _, err = keeper.Instantiate(ctx, codeID, walletA, nil, notTheRealMsgBz, "demo contract 1", sdk.NewCoins(sdk.NewInt64Coin("denom", 1000)), nil) if err != nil { err = extractInnerError(t, err, nonce, false, false) } diff --git a/x/compute/internal/keeper/secret_contracts_exec_test.go b/x/compute/internal/keeper/secret_contracts_exec_test.go index cb5a64ebe..036935afd 100644 --- a/x/compute/internal/keeper/secret_contracts_exec_test.go +++ b/x/compute/internal/keeper/secret_contracts_exec_test.go @@ -350,6 +350,9 @@ func TestEnv(t *testing.T) { // require.Len(t, actualMessageInfo.Random, 44) // require.NotEqual(t, firstRandom, actualMessageInfo.Random) } else { + + contractKey, _ := keeper.GetContractKey(ctx, contractAddress) + requireEvents(t, []ContractEvent{ { @@ -364,7 +367,7 @@ func TestEnv(t *testing.T) { ctx.ChainID(), walletA.String(), contractAddress.String(), - base64.StdEncoding.EncodeToString(keeper.GetContractKey(ctx, contractAddress)), + base64.StdEncoding.EncodeToString(contractKey.Key), calcCodeHash(testContract.WasmFilePath), ), }, diff --git a/x/compute/internal/keeper/secret_contracts_migrate_test.go b/x/compute/internal/keeper/secret_contracts_migrate_test.go new file mode 100644 index 000000000..53260e4fe --- /dev/null +++ b/x/compute/internal/keeper/secret_contracts_migrate_test.go @@ -0,0 +1,28 @@ +package keeper + +import ( + "github.com/stretchr/testify/require" + "math" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func TestMigrateContract(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[migrateContractV1], sdk.NewCoins()) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[migrateContractV2], walletA) + + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"Nop":{}}`, true, true, defaultGasForTests) + + _, _, data, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"test":{}}`, true, true, defaultGasForTests, 0) + require.Empty(t, execErr) + require.Empty(t, data) + + _, err := MigrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"migrate":{}}`, true, true, math.MaxUint64) + require.Empty(t, err) + + _, _, data, _, _, execErr = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"new_function":{}}`, true, true, defaultGasForTests, 0) + require.Empty(t, execErr) + require.Empty(t, data) +} diff --git a/x/compute/internal/keeper/secret_contracts_utils_test.go b/x/compute/internal/keeper/secret_contracts_utils_test.go index 8ae91c466..24e816d9f 100644 --- a/x/compute/internal/keeper/secret_contracts_utils_test.go +++ b/x/compute/internal/keeper/secret_contracts_utils_test.go @@ -546,6 +546,7 @@ func execTxBuilderImpl( execResult, err := keeper.Execute(ctx, contractAddress, txSender, msg, coins, nil) gasAfter := ctx.GasMeter().GasConsumed() gasUsed := gasAfter - gasBefore + require.NoError(t, err) if wasmCallCount < 0 { // default, just check that at least 1 call happened @@ -630,7 +631,7 @@ func initHelperImpl( ctx = PrepareInitSignedTx(t, keeper, ctx, creator, creatorPrivKey, initMsgBz, codeID, sentFunds) // make the label a random base64 string, because why not? - contractAddress, _, err := keeper.Instantiate(ctx, codeID, creator, nil, initMsgBz, base64.RawURLEncoding.EncodeToString(nonce), sentFunds, nil) + contractAddress, _, err := keeper.Instantiate(ctx, codeID, creator, creator, initMsgBz, base64.RawURLEncoding.EncodeToString(nonce), sentFunds, nil) if wasmCallCount < 0 { // default, just check that at least 1 call happened @@ -696,3 +697,88 @@ type GetResponse struct { type v1QueryResponse struct { Get GetResponse `json:"get"` } + +func MigrateHelper( + t *testing.T, keeper Keeper, ctx sdk.Context, + newCodeId uint64, + contractAddress sdk.AccAddress, txSender sdk.AccAddress, senderPrivKey crypto.PrivKey, migrateMsg string, + isErrorEncrypted bool, isV1Contract bool, gas uint64, shouldSkipAttributes ...bool, +) (MigrateResult, *ErrorResult) { + codeInfo, err := keeper.GetCodeInfo(ctx, newCodeId) + require.NoError(t, err) + + hashStr := hex.EncodeToString(codeInfo.CodeHash) + + secretMsg := types.SecretMsg{ + CodeHash: []byte(hashStr), + Msg: []byte(migrateMsg), + } + + migrateMsgBz, err := wasmCtx.Encrypt(secretMsg.Serialize()) + require.NoError(t, err) + + // create new ctx with the same storage and a gas limit + // this is to reset the event manager, so we won't get + // events from past calls + gasMeter := &WasmCounterGasMeter{0, sdk.NewGasMeter(gas)} + ctx = sdk.NewContext( + ctx.MultiStore(), + ctx.BlockHeader(), + ctx.IsCheckTx(), + log.NewNopLogger(), + ).WithGasMeter(gasMeter) + + ctx = PrepareMigrateSignedTx(t, keeper, ctx, contractAddress.String(), txSender, senderPrivKey, migrateMsgBz, newCodeId) + + // reset value before test + keeper.LastMsgManager.SetMarker(false) + + // simulate the check in baseapp + if keeper.LastMsgManager.GetMarker() { + errResult := ErrorResult{ + Generic: sdkerrors.Wrap(sdkerrors.ErrLastTx, "Error"), + } + return MigrateResult{}, &errResult + } + + nonce := migrateMsgBz[0:32] + + gasBefore := ctx.GasMeter().GasConsumed() + execResult, err := keeper.Migrate(ctx, contractAddress, txSender, newCodeId, migrateMsgBz) + gasAfter := ctx.GasMeter().GasConsumed() + gasUsed := gasAfter - gasBefore + + if err != nil { + result := MigrateResult{ + Nonce: nil, + Ctx: ctx, + Data: nil, + WasmEvents: nil, + GasUsed: gasUsed, + } + + errResult := ErrorResult{ + Generic: err, + } + cwErr := extractInnerError(t, err, nonce, isErrorEncrypted, isV1Contract) + errResult.CosmWasm = &cwErr + + return result, &errResult + } + + // wasmEvents comes from all the callbacks as well + wasmEvents := tryDecryptWasmEvents(ctx, nonce, shouldSkipAttributes...) + + // Data is the output of only the first call + data := getDecryptedData(t, execResult, nonce) + + result := MigrateResult{ + Nonce: nonce, + Ctx: ctx, + Data: data, + WasmEvents: wasmEvents, + GasUsed: gasUsed, + } + + return result, nil +} diff --git a/x/compute/internal/keeper/test_common.go b/x/compute/internal/keeper/test_common.go index 85ab1b776..5717a42d5 100644 --- a/x/compute/internal/keeper/test_common.go +++ b/x/compute/internal/keeper/test_common.go @@ -113,6 +113,8 @@ const ( evaporateContract = "evaporate.wasm" randomContract = "v1_random_test.wasm" benchContract = "bench_contract.wasm" + migrateContractV1 = "migrate_contract_v1.wasm" + migrateContractV2 = "migrate_contract_v2.wasm" ) const contractPath = "testdata" @@ -129,6 +131,8 @@ var TestContractPaths = map[string]string{ benchContract: filepath.Join(".", contractPath, benchContract), evaporateContract: filepath.Join(".", contractPath, evaporateContract), randomContract: filepath.Join(".", contractPath, randomContract), + migrateContractV1: filepath.Join(".", contractPath, migrateContractV1), + migrateContractV2: filepath.Join(".", contractPath, migrateContractV2), } // _ = sdkerrors.Wrap(wasmtypes.ErrExecuteFailed, "Out of gas") @@ -136,6 +140,14 @@ var _ wasmtypes.ICS20TransferPortSource = &MockIBCTransferKeeper{} type ContractEvent []v010cosmwasm.LogAttribute +type MigrateResult struct { + Nonce []byte + Ctx sdk.Context + Data []byte + WasmEvents []ContractEvent + GasUsed uint64 +} + type ExecResult struct { Nonce []byte Ctx sdk.Context @@ -682,6 +694,24 @@ func PrepareInitSignedTx(t *testing.T, keeper Keeper, ctx sdk.Context, creator s return ctx.WithTxBytes(txBytes) } +func PrepareMigrateSignedTx(t *testing.T, keeper Keeper, ctx sdk.Context, contractAddress string, creator sdk.AccAddress, privKey crypto.PrivKey, encMsg []byte, codeID uint64) sdk.Context { + creatorAcc, err := ante.GetSignerAcc(ctx, keeper.accountKeeper, creator) + require.NoError(t, err) + + initMsg := wasmtypes.MsgMigrateContract{ + Sender: creator.String(), + CodeID: codeID, + Contract: contractAddress, + Msg: encMsg, + } + newTx := NewTestTx(&initMsg, creatorAcc, privKey) + + txBytes, err := newTx.Marshal() + require.NoError(t, err) + + return ctx.WithTxBytes(txBytes) +} + func NewTestTx(msg sdk.Msg, creatorAcc authtypes.AccountI, privKey crypto.PrivKey) *tx.Tx { return NewTestTxMultiple([]sdk.Msg{msg}, []authtypes.AccountI{creatorAcc}, []crypto.PrivKey{privKey}) } diff --git a/x/compute/internal/keeper/testdata/bench_contract.wasm b/x/compute/internal/keeper/testdata/bench_contract.wasm index e5677e96693799827a5f7b4e400fd791223cee8c..ae8509785ad71a585663f525a10868d8ef178e9f 100644 GIT binary patch delta 20323 zcmc(H33wGn)^>N*&DvQmWZ{M+&+yVTlMB5SLLCAP6Wz@CGW5 zh(Y5BPLyEKMvWRYI#C&oOdO*|xWTBPC{Y=QZ)Eg)Pj&arO~CoT?|=U1`E}Z=^PW?u zPMtcn-^|lheGljLFJmsP@!V-e%T*kx%5kn(SOT^q~3*j;{=@z*f*c)2<;vJ(lqS50A$ z`n(HQO^JBam!}w-p&D;L>MO5U^*N_vkLG+GL1}*ONlwL=Z0Zuh>UVn|+&PW;c9;8h zei%jU@_mOHsav{#MRfkIN+{~7Goy}Y8)fAu_x~EDR(U@!+eQ*<=UDGOhY!RG)RxXd zb;anL&Rj_D7rye0=g&v7bA{#IE2pUJk3R3+$1;(WR~&P5R^;=(UzJG7w^fO=i^$j* z_ph7s@|4IB6weDDqAC$#nywmUlBwIwU}A<6GnAM$#MGJ13?gPYF++%X654NmE0I0o z^WI}6kGz!}_eemAF_8-7-iN?@Zw-Q6dGOnNrKu%<(LH~Jpb>7V9uvtTRML47?Wq4t zw_xdB?!B$7gST6C857hx-TPnFiIlB4w$i)top`==Po-${Bby>Kr*3Ac-spGVqM5FzC-Qg^aD4lRrG`GmAXxp zd5ZgO@|vO@(7h8Hr+Oc242z9cRK{IF!6Bhx(V8A)gk~E@y)QS8$SB^80t2}MtY5aF zbms?}feZ{K55%_$Ze2}hF<+#v;H}Q=)jL9^@VV)m7eCzrWfO0-HVAMyMX% zCJ+B8iXJsmy(cBgoAF&*yGCVdWH{+D)RYjTG9ptka<7dH_l`T?gMGTkyYBpOHOyOn zzKiEuX<1&Ljuvl_YN$j+X!(SuL{$y(PG}nFee8!@bAzq67@tb{Hby|XGzJUZc4-(D zna;MVQcDm;5^PkuD`iw}AdFNEw*(F}1L!tL6gLB)iX1A)*orvtZu_x&53U)yp}O~2 zabQ$ENKPGy8jrGU<3a&Z)!Xr3_uJ(^{F*O}J&Haz52V5hIq0~q+swwq%V*Xx22kIe49h_PA7*Sj4 zzs_7?_?pX!2cJ+glO89To<tz4wEc&J6p`urT|FOgCUd$ zr?|gooq6fgK5=iUx~0bxWZ|D}dx9{Q>jUdD8i{Z8FbdGLKF_LQJp2FwNydQ#K4Fxp zy;7eBoz6TuAE^#x5vXJ9L5YMSi;1P+pwHY{rd}76OE3ynJ%iNm6V*7TjE@Y0v6YHZ zD_OQNMzLMs;-3Qw7FQ%@GT}RpsWTm2s&s~&nSc0P{mMOw>LrEkCgk&XTMkPP}?3Ml`i)aSge&4 zZqyv{ndwdH9JLQI{5CsvluER9%@s#{;`JZYY=*SwkLt)yBn3xf@u{`57&?_Nkj6Ky zu{jO1vl=h{^rN~H7usiP9{Ux`5}i#ww#7*;k)#2Qta;V7&MtOf(BGDtDlYb1W0qi6u(V;AEPCYdZUZ5$b@KnnNU;?$;@Wy|Xa@$fRRNM$^ zZYdhIlhye|zhNwn{jP^s4Py)0DWCWdQqfXHNVAH63}c&PUx!{=@R+sWF{1*l*gulR zbw;2tBMIS1Qynw5UnY6LmK62Fnfr1@7yoW45^*E0#IASP*IkiaU@7l%x!ww=VC4wb zj(y}4?~Y0a6{Pi7oYjs zwd|Z~YZ!0-V?67~S*1_JPi7-9FNm3wnI2z3aWfE0@fpk`vJZ`_SAF84$?W$3g=~f> zzm8qUj`;+i!e){3c~hE|2N@Rwm3vno9%LS$!eYZ|M4X<@Mg+_Gf_pDMad&v5%rp1L z8@%^CIV6xg_GFsrnZpjK=q+!L%KOc6^VlLa?i97a?OZ6(k#CC+3(kDjk0JeGKGQu? zB-#f~dlX>O`^bW<(9bLEbPFB7@_>BmgFYCWv{eAne~?*StbS zlZ@IbpE+R>+a4TFYy)S&w=lUbXIEcSO>`flhEo3lAlhi3jSc^W7P^|Gt`wsXy2h_y zMJ(6W)%X^bwHH<0g`rj=5oeR{7*QA~XE^AQKva*`Jw~lW4p|GW?tvi|(pn#{LL(Nh zWKHZ1pE>)l74Y$bU1i3YXzB3MJB9h0CrY*k46Si!wn*ka46{nIOB2%U`CdMVVk@ zP_R+ks!*_9i1`aOwkQ;0ptIk^q`!t;Ot*bl73f2Mx!NnDjc;Q--Nwd*+hy}Hwo7kg zT+Nl@&UuDH04QH?& zcu$_|VnoqhEYflBQGkc;V&A8dCR+PcYwc5wy&p*=6mtw}D#6bgZcHiL!gxzX#L+rAsbuUvkwq z15k%+t=eV))NzzMbuasXedrTYH?Tr6I+t~^E6dQOQN3`au#HMXHcc93KA6i?b<~Gs zgRITEV=Eybu=>5tfK`2AGl1&1quLMhSe{+|+jA}V{->JJ;Ro$`%4H0-w;C>ItMQ*o znrk<*Au3f>wu!y$Z=^i7_kzRxjihjtp5LDD@5v17cz;DX^X+^Vtopks)as&8qx6K` zMWNJ{M^5<6?>Dn2ngv5F!H{Ob5E869;S2=VW`LL6rV zl=MfHEQzQxcW#Bv{wn-7pZi;&%@>IB`#aQMMQC#s{*nbPN*4XiXa2Aadkxzy<8&!F z6!%TT)y#AO`Cbs$PXUx>KAl*Ni)_OSgZX6_U0Tb0V6 ze2(=LFFwLP&$1j;=duRzaimUwS5v+kCv7x5pm$wHJuta*_YbEQ#qH?x7pJ)nb56V& z^(gy^v3j3a_9ylU|ES()p4!Lm4Fb^SA2LFukPTdi-f=}D!m zf^amazd7Vtwx8N$qD{j?88)CDOxBb3krPdJmeTa2?6C}cnQ$2eu-?B}MZ4_B8vjDl zNnFUekZZL%f8B3bbQ!P}?d0ehGO)F{f}x@> z|8CLdi-OEnWl<0(B)b*A?-cuPv>2_J`UY!vU8$@J)wZ_ff2hyCJl$$pe0d-h5W@*1 zT&qy?&S4m$a!n=Z?k)I&&c9wMk=nIW63w09V7ur z3?XN~wq=rlv?b(y2T26dhLA%J(h-Q8kZlgq6$sv!nbGi-ttSmg6d})im1{!-0pY=y z8JirTZa`=>8t;8+%VYqdVP|*)5gK2{myNbeAIQ)+GXCly9w0P4jMp3_8VE(W@qD9i z4mmH)hyWz-e}p4MEu#=ME`4FECWJ!Dc-BEapu2jC3gd^~FDepQH9;Gp*7sxYApB_Z;>mpEAw1H^n#(ApSG9GraeA(p7Y~ zb1E;7+)s~yB|k{CW@}Dv!)_I!QhS<~0%G9M0(pub>4&Pl3gk zAx$k1dI~ISfsmfcW+X|mo&sx{At3Y==xef{0xxcC5CgwwTY7v?_BaP+dJ3$NHro~& zRm8_rVAJ<_nSNHy5jUM@53nD7qNs@t7J3tF6D#{L@M^RSY`Pj1vcu;$u?&VDL4kSU zKa#eqj59xB1Kh+q@PbVZLjQryYD{rGHBWI$` zKeADApyXg|-W=3||M`#X`YW(}V2%8Vb>(M}x#cIeRAy>_V$*qEeuLTT0USd;u>9?oF z%a_>EL?C&}ZK*iob6s(NO{e|k^yEhZ5B(c0D?N8weEn~BS4;^>W~XqL$ujXc$@W6m z+Fw~Jr%chW?9Q>s+#`jlw->WP;8J!1Y zvx5WdX zW^B5qpy%O`GIB^N%$OKSt2Fh>ql`}@JXI+zap~kqWnyAFlK^?Zikzdw zhsTU6X#1S=&b$s8my7qgMzY*_bfFN5ANR1i)qZ-WFHgVI?Ifyf4@vuZnwK9WU&hNn|0u_&0Ya>flhz-m2p%oo9S1cZk0 z$Jz-LHs*0*E5uNY;QNr-|0FoYS9DKrX``gbBc@v%Xd;V z6+z+t2Q@DhT?j}V4CURY)sfw_)??j5Kf+6x)JUnV-wr9@?!QrCh@xp$5K!AmRECCK zKk}kW7@vB@7HBa|ZAS_(@P zWh*RhH4^*?6)(3IEn$#V7Fk0{v$RA(9=Eu4HrE!GD7dv2*JpEWVTpoUZ*kAqT)??x zri8(6wAf8H+m@DSGxwa$m1#P=*pj?plQK+Hg|v_!$JwYWZ;YYR&h+ z5(T%>;x^gb`do{aFxclT@}kYQr6mgP1&f>at!1<=EKzVTS=_BQ*A|v2xcLO5Pi?L( zoS$pc+bwpHP1@2DMd3n=TijAuqTueexCd;mEiBPyZV7SS7pt<_7pMJ`+7a5Nw9pKbA|<)3XM-Mo9QoDFGPfMwC%c3ew)7#)s9Z8DPl zGa;VY@Eb*c-R__4nx(Woui9;+det<;HtDV(Vn9pOyr%#XKnZ!a-Ue-mJg1R z`!y^^(3nJv5oqyUTmFcY*cQW+<=*mO3?C&k=VSPxRN9y-#%~=l<5}K9N6@1E zN-XaoH#%oxxfmclsmtwGi2DP%+*lj0)@?@@$r1g z|8*>QuIyQsDco+}UfkG@yZ?Vi#n?zSLVVGV&${W#cK%KTFodiVn{p|?Jg(qd3Kmi6NN#L2X1D{UdDV&h^5)cP4N_?BZuTHTB8MnHI zhKaqQNRbBs8vU8=dG~mGRA8WDe~R51Y@`Vxw>_Vk4omXzc9tTq9~Ae86c@M1(P!(j z&84FSv>LhT()fr(o;2Kwwp_V2l6g8JSt{B`Yq-6^@0!-9V$<$FSN!f^m>y+ssc6iT z;V>>)Xi0o9CtrvDnNz=N-}5fv=GMy}lz)l9|;V z`JxGyql5I2Te4HJ36&(x6=|$ajzETeIIb&cCoTbtXYJA%d0prBE?p$*e1h!lCC%Jq^2{U>A85nbQc{a5EzOUi<#5_C`NSQ-Mbc%XH$dm>jrF1 z>}?L3?UNG?W>=i4kQY0;@ZMK#w`FrD(S!u2f)B$b%rePag;Ijfazqs%j=%51uZfis zDZ#Y)4K{L76998ySN=NV)ms|O|4QQzGhT+ymIv*Rd-AWFp!z4>vgU|Bz&9A8EP##M+5@MU@95~RN9$6pFcII;~)cQu`hFvT;Sj0rMI zwl$b9r1MC%TNCjEe}ZRShu2Ej{>fR@wg&ofUA+5~K-32`I)mTN>vlDW*9YaC`+0H?g)=U@A~n)x5^8>4d$OF@C7Vv+YU15K`4rz z%&+6M51~nu`EZ^OWdCGxB9Mh%Tzpm#U#mwt@F)w(i!31@U%Ikm+xPh`+k{kGF z&Ud1wZ>M8U-a+=w;2Ujoy&(TM11t0{WPCHQ1tTlb40_m#YnjmpNS4RxIX0rB%qyaT69yE(k0%nX`?Q$8Vc=kTsFv)Rc!H-{%^I||6} zNk(ZwgE%pVXGoFAxtKSp(15vip*eGTCy8vBi|`}XM-KAKTs~GJqvv6=2Fv`zJoG5V zjCt~AzCDOnKsWtSiuphmU#m8g$;%r7sOx=t@Rs=r! zeY|McOiOVIb$(BY$}T51x;#lNz8}|HB~QtI@6n@^(Yoh5UDop-2g{y6c|Ud+m;P+m zvSbTt$t$%&EY2Td#FzC^M%MS$7SvZ$YS$NcS$%Pr)n_tU-@>h!501Zp>1!)r6I=HJ zTt*Y8{2K{)uI7aXv&%Mqjz#S}o2n{CUS6f5<)2Lz9k-*G7p-0-78+WA@rUiWmQzv` zw=zoxKNDKE6=55)JNoq!3V+ z+`eYzip2}pW$8;-WUXAHF94>5xs^6Z&WDN>yLs1y&Nh7w(g@&vm#@Axt8ZYdJz;CJ z7Ou=%(kExF_;ok$GU!H#&Vi`M{v4w|K%E1CIkXFOm)0r=h@E?QuMW!Wa5r43C@!Sa zkq*a)Cn<{-b$j@zu%os}wdgE(r?9U;lI7LndckLJ`B-p#E_^}wg7Jmm3&j^^ek{WK z?|-p~`{s+#LE3cwg60v625J5I_sHxSq-H(*o{}R$Tr0+*~#NP*N3u7ildX#VgGmuh&J0m?}!Vv9qJ|xN` zdJNSjI-T8L+`3E)7rxlvmEjFVY# z@54tmSga+(v=m2WhB!7%>l&>1qCHBMI5$k2!|!pU`r+D4N2Iydm|*3So9ekZTpO4x zvrxLvR_@TRfY$LjbOrMGBd!)S^|8ahggp7hp;g2HmdX}%QUJ}sN4Mwt1qet95b%KR z(~1rYpcB9kq}{FLi4Nqq1x;hbF|du~PiqEZTNQ}6>G8L&S-p1cibX54^qj0)7p_>f zBrB(^tw)IsP}Uc+@eVEWGPU>OR>pXgUii*Iw8hw38mt@zzDgW7v^jBeV)3hAO-)Pg#eT23T6lLSIsJ@F9NO`hLp%O*=m$|T1&Kq` zAf_M-q^SjgGzCnu0}KHXC}0pRt{;oOmLg*L1Wd5@!ZAR6FhTPKD;JVH$_?V&1Z^3g zmFzKROw=M(en$t7$bOjj5)V((zT~AHJ>u@k+C1(<=F`bqa^G>fM-I`MNHL(UxQs0a zj}`;Sh-@rM-M8DoV@PQo8;y@9c>1ox*X(q;nq%(mkb4}mwDz1pEgg|MbX_a@Gtks@ zhu_eO-`I-(O)LI)t@uA#{9M1npIZrBYNg<}R{S8=(%?|gfd)pk;cH=*{WcNZIe@0syn6th0-AcjaY~O?e4=SCbohN*@rh2OncorU4S+UI4t*8q zzzPh|v=lr1(V)AvqG<_t_}79@Gm1mc0!>T1LoWs0oto?bcLE6X;zrPc20Q?o)_N%~ z(xz%R_b%*&Nzs9jJ_eCM8xI7k6i23NLlT_Y_CTDL@yi3Vt(bI!)-GIG(Af<3~}# zZQyu^q~(;%q6iPgM-e^+-}a8Q@G8m*do!_U;o7Y9s|V}7x_IPHtGOb%YaKdG)8duU zU@k@>ay)IvByG-}rp2%})!>Dnm1GR-5p&d|p2GGtcG(2{vA zGCO8y!;B`l24A!xC>;*NmwG?d$n6!5N0YHzNwB&9D0I0J7C~&Z%uUfrMU%LACRZE(? z@hF5>-Gqgt7MXoFY28P;dV3UFw{@h{@y@Psr0i&Y?Yf*5tCpeS4DhMCYqM5m<*Zn& zXXWIq&H+BFw?~A}(UJ$QfdCE7X)BhkLJ_|}0dU$I%|NlGbZ}U)dX>XG(A#6qpQGKX z#Yz+!th6n|nu@v!F>@ELf`b zj5%(L_>hv?vl$qwOSS$zU4uMIPXNvkU33=?;h-~sQ$Pn6_}5ZMqAtS17vAAY(z@oiW5oB z!koMMu3fi8o=_I9#I_kD!Zpex-dLk`kLfkan!m=v8rp7w7Qe31Ue#Qqt z&E|_odqirE)+J^;I23UQVfav_pv{|dG*#s$LGI?|!XEoVZ<^9eLw8OZ8HusbbAtTCA9~UW?{M<6!T4Ejgwd44Mq308(P?Sg-Yu zxd;Z$%2DI37$L@q_1a|5PypoUsYofPUO??+i7@Wa){E=!z%7D#hgOw%WP){<@j6mc zrQnR!>zymWc{Oi<~S(h581 zXqjR078NN5d9bLksHn`atf=rDEKD=aOIB7^|KFOu_hEz7`+m>!J%4+4GwZk3tXZ>W zX3g!eGppY-m3@ktLp!?TkfLQO`l%gyOo0SxQVebYz7MQI+UO&7N@TSG z-*O|_{8n;&t*ykE7zJ|sAn^WMgCJKD_VyN)Of7iFlW>rXiZWD>iDA(y={yH!?K@q= zq@%fSadCTJ*Q#Rn1+~uO`=u(8vgLa+e5>AV!^<{Sh$l|7NiuW#G)wWdeD8h!?dO4# zgYWGLBgy>zCy|t_|LEOFa_rRFYU+vJ2XA%~`OsG$B8$JeOYLa&2-mAr^oZ=An$_qf z*W2VZMSIliyR807-{yKP&ZVe~JDg$R5s@y<qmWM^&`@&H=w{kt^n&hUst;E zng$?U0(Bu^6a*6>2&pPxpTlWttZ(*VkJ{R|=I{jH*WY$5`T6hdP06Xxp? zp0HL~_@|(;sVqlLQOCqYd0LE8mwQ_<$fvS(YD%~q0G@DNb=8rq27!9z${3BR(p7J` zUJ*S~(KE-!XueBNc4uY6x8&q-HOja1WarFx1sR|JMtd}DrCHM`r1GCSkmsnLaM+TA z?uyX=R+#-qVX}p$gHt~Tb*}jsi6y_CY@zy2oJ{xWr*F%o0S}+*Wzwit_WGo!Tp<(n zm^8RUDh#6$4PPnUlsf8(fpC@z?F7^`02n?1sv7`MRTgD5(AVosw~-D__rQ}Ijq#{g zt|k8rgw17azMd~fY}Gno)`->5=8{AYy^xG{Z7<0>vsI0(^AYIPOMP9>rY2B=@%rCnoNOKhyvc5m43kl>VWrK7>5KkEx^EL(X60QKwLp z^Y`zlc4nbC$MwQ6%qst!&gw8yE1vG5c2R5mAM{Y)S3^<`y$~%qFP`b8&T3;#NQa)~ zu$q^bCsKN=L->!M2mH76R>Ry>)7&xY97hxJI z=bLrwx z&sIN6v6r9;##7ljhN$L2%VB;o0YXY?kZUph;TKYIw_(1`QB zj5uF;C?HBUs<*PbfX`KuEP7nRy83Sv>Q}0X_@{1GJ9G9`zzBlX$WRazKW|afsDeI^ ztA&nHUsIS((yJ(SZ8tkQJ4on2%*+~iytt029QuD~?9?@s6K$VVM<#tmGClNSN?qlK z9#5nvLa#u*cRZ=~aX(E>(4(QW5Q|!cR9cEgyz->_T0%W|X-x4b`iq#r$R;6Mc{Cu_ zKLw8?z2z{=Xj}0OX)m&dBNc+}#oq+{Jqpwv4)#qz)E27!q9ntsSA*VvjE!iUd!)H? zSw{k5(X;AP3C(J)gVyfPsU9`ctS0{`DKTB-X@RMlFV#L5YAn}_8zJH7-iiy5T&c$@ zMS7|m$wZ=5oefFU5Xe;hlnv56VGzoKTehBHop{l)fY6H6HQf)Bh0mMzI5G8W?RDw( z#Mis)xoBE>ks8UPz9S$>FZ?bbKHQ=9OgRQRjU{;aD0Lul>+YQt<)_nO%*R zc=S?<9FeVy(Lx&YP6Yfvzoho&u9HwUm=+veNmX)A2K*QAR$pWBr>Tx!o-hivxg?{P zo(}jU%GCu9b`oQ=LhVB7;}wWmNMAM6gJ$}Bg_=xw(jIlPrAw90uyl!>J?azfPC>KF z>Qx1c0bItG>G>$Czo8CpzNkO<4Yju#B~47#kDm^RsyEd+>P>CDKf(-Sa>~Vtoj(g;pq#BrH+J@HK-~MKI*k2*QT3%7 zt?I9b1anrL3LXhE}R z=}!Uwknh#I)Yd=+a;*Q$mf5wh8;qe!AnYcBseASRqv=QE_c zPphLkk`&yGKz_i?Vy;x2BaLqwlksZAV6}}Ha7JD4`GrjI>V=esT6IdIn2Emx{D;q| ziE8GrB$lL~{mm|xYob-Z+tK{QX8+r<Tn`Vd3yOv5Y)WPUIC?~AEX!Ti z6Zr&2g+Muz_B~2qs}P8pr0Qi7Y!d=Gft6BcYzUN-ra(%@g+NRinut8>(V*z?I&-@o zkOEQ01k3|^`yh7f_-#~aj4K$LrwPV9)%QzIq#<5QgzFU&YDcqKPG$YL6p1iI%Cm!_ z{b1&9*%a(GlzGLh!Au|Bq=B+6O&j=kZTah_xQ4L1SV2(SKZIS>MH=94Xp&)U(G%2C zIECU*-jhLbXb5v(+yrdYNbG%$q6JSFX{KEHnhg{Nc=X zp_+4>4K);-|5i<{At-8_Rg)_#>3pI7a14|dg_6ofBaZ>Ts4abY;1e_SC3;II9nYQ1>@NW z3JZtFGf$g8DH0CE(t8wPM0T5AnH3a?6WAU93)ys`Ph=ArCfNFk?0QoE-NXjvI0f33 z`@NIcgeaN}w@-m3NOw+QnUOMNFxO`*eaoL35>?+o?s+QJ|MU&4P(_#caY1ubjhBPd zW!-hqDR9kGK{4TG)|Vm8ycvr)`gGgPERJaZ&8#b>bvLs?)UEQ4BM%w5y?=Nb>rR?6 z0-P*i4g49}FjxOU-bvCAtO@#Srn7ZnQN-50dUg(C=Ug`6;_Z*yD#YfI)iOeGtK4}+~3F|U7ere^f)HPM2Bjvyw4_~GyHcz zBGz`!p)<2gRH#gSqcU9Q`q?IB#IFmPmSh@{{V#hJ4&9;W{R?A$5laY}*+{~vJM~hD zG#KGDjc|mFsBBawOb^o!G$|8imSLeX^^MAe>rQknOnG$?JC|k}TWR-LsNjKS(fa#? z;=9|~m?*2En5}~sGp=SzaqBcf1L3UfN(;fUM$eNnR#)O$L@%{FF;sQ79DCMA%o;4& z%^FlnhF}2V{t5STda*e!&%(|RmayBcF`u%d3lLD*>6YgON7s?%IBv%W$HTSSL zLvjv7pFqFXuL@|j5nLj;h`;0xMj1gWN2i` zk{DV3sv>0b@r`zy&k_}KOGK!Oh=wXcC372<+_W+1&%7Vo2h%P8@JPX-xSKMo zNJlmudsGn=53XfxFO)MCnsV8YgF?4IxRzbRLWYMKz6ooXi(%x$#=Z#)86MVPc&KE^ zH?k!8=HZ9fKN@@!5)8Tj|DcNgxh&C1`-v+yumnoyZ(tL{o`SpeaB=%~)>RzdfDH&3 z;Tzdy9)n>%`Gjk1q^C7q<2&>+-0Gcx)Z&e7H>CYN1^Z5=Vj0_64{^z6c5s$4^lKc( zl-`Tf8vIq1ufho$jkfi(L$3uUci|4pUyX{JjtCW}$cG5j#=qrJ_5)*2UgHsX= zEQb7ySJ{)H*}#n1fSr`J;>d-uargfH;V3l7Wl8GU>94Vs!{kxEWy5LHy6DnBC4cF3 z$AJUqITAAu(9zMxQE_j+JeeolY!|Gt3*u^?&hXF5I$Zy$j&gg^D5EHD8szD}lV6^6 zxnT{?>J8T5A&Dw^1d`RSWB>P;f_P&k!FnlRZ*hcqPX0l1%=>`zMA)tjLZ|6{9ej%REk1{~YrpqvG#Op#w2Y`M{{K8OMAgIkd~8+eUkHao0jcU;fLYZ%7WL^pQ=< zqM#CL#$P+syaLTfD}sBNJG0TvgWZ<@QXlR~$l{#8w7Aho%Ox>uq~SJ&g`w1MG_Nlzr9kUuJld#|TIkc?U`yG*gYrSBeeny>Wn6$I8xKP34Fo4=*L`B* zX_n}BzsVkBR6?E*^O2D!#MHOhy_wI;;;DKH?v>-n_xD*yTOhH7eEXa!lLVwSA^R*O z5lAaSc34OUAb9O&`u!Ht1xQOm4n1q?Nd@6^wa+~g@yv5zSqm(cIQBNh60wfZ5m;#}E|3A@@B1lMfjFZ{wo9?P?eaED86nw!Rj_Oq`okUkU!G_1Zf>MblcANlAMOz#63Q_%hfJ-;-^to7GzZ zy?E;Dpk`V%Wsz}K=g7CdtP(=3vpBucWfk`QL*06YS$tjj3wx49J;$(l???Q`TGP?cfNj6k7I;(NP5mBU0@2?-^L*7;_pj6_AmEi82UGv*MAF)3RY(Q3KY3 zGwh0HSoL64pJ842ab$iu!)D9Otv|49dGcth)KFi-p9=P@N{phL zOuhEqp#Pp9+4m~Xt&(?=#sy>P&uo~37Ze>5XMbZ?^5X4>#6QlnvP2+R%HkAdObquZ zt|O~(%`lf<`bZ%0cQmYc$02dY@9dwkg(NxO%h^aa5^s_$AG*{(SPG|1mp|CuGPCUu z*0wv!WGNHq$5$~biONc-4j@hHsQ-h#&_~LrIL5@#zM0>d5~1^Dx>;WsDJUa_UWZj} z#hlc6?mG5hr2O;Er(*Ul5tO4vxZdC56>_i#SDEfGv1?} zL}7p<&2XK^;o+_ysB^{bEqL7Z@&|9JEW(S|WvZ`&w8-BX}ORs`)3pnq@Yms?`^WGOrmMe=+|1n%M)PX6R#u3b=IthRXn~x4A z9Y1nDLX$;JV1$DQIRN2x^0pkl5yPB(^3)n>bc83;b%t6-FK;LgZ?y76(ODIAHPQ4o z7v*V%1Rimwu>%Am8qQ>h;ohnYRSF^oUaN}B0W zE;YK1y64hxeoHI_QN;?3G=8T!w8ZXk-l3h8Hyk1R*n_KBxSQH^CY*QjO3>g-(G-jU z*N@b^6!azeU|ojx_a~BM7+bV=4?$+h{QK%Q0fskGv>} z;8!-=Vt1t3;-QgzU}l}^vj5~rWB#IP(iMs>rz@IZl5%!q#F}Ior5IX`g(V7WD-7;l zB>2fIewb#^5(ZgikOwGfkd`ROYJ*#Aa!p~0f?H#7>rJjHEKzXl4DNB03pkU^lrY#w z4fa`+ZAweDfqTm2$~29gZ%m#uNtvdx>=%qSm}Hho$~29wdx7eQYLm_}*)mOId5y_j zlay&1+tQfaWRfyXV+D=Le3O)E8Y>EsnX;b>O zHP~BB(v+4c3U4yF1&xIz3U0o^Ei$>LutXcUg~WB8GeQr3fpC~|-f*!Xh7Xg$`1u$! z7{3$4CtoUqF@g+!hGJj8CQx8Rlwu1~5M%$V=;jgGE%?-nY&=V5wZspo5Sj{DN`26HB5|X$;XAFF`l(T(fF~Jyj!M>mWbV0 z=V7!}BN=S2n{WphMtyi_v)64br>I#N$>WybKfiM*4T*NVR(w}8D{ z^TDxlcZS6ZrX|s01zP-1Yra`ZxMO*;+%^u3<)dZh-dMgPxtdmi6xw$x`kx&T5sg&= z?w}QXTpaH%H#~R7aUnM?u6Ul{mVOMi6b)h{WxtJx=U%hloMyk>7S9K8C=~_qeCGe* zSV(Bzvuvc;+LE`+RAG|wpD`rQYe)vx8Ysk_E7tkz%n22e|C#S)ZEIh1voc-7cTUWyIBb>tCC+VgqR z-GTNzNoIa;&u_iV@VnC!zFOyRH5fmEm+c`iQ=B(EcX%tGSCrJZ=Zgm3P|CnubLS00@)8z|f>S{!1m4p4m1 ziFfO=g}jYZnTk!X%p2{immvso7pE@dMN((ptADO3n>k)CL{umR)=QX;B$sWH5_H-l zDi33Od1rocoRsi}QFss2Gf@)&|685;>x}PxFX&&B${%68^gY`NdsYvAMD1Ano-`d7 zLB^ATqHlR$BJ|@vdO&+W=wH-}@0Eqc@V-2`O(_ZJ{V`U+m*w@Wy+QxtzI?Z{ZP{Kh zT~+1-D)W#*PQ4KP(P=zJ?Ru8@_Fv!`zd5Usu=$&_s=e~Jb!}V+?PxvF#|QE|czJzUy_FLKD-jt#9{nOUii5QzdZ~G^D0o^597D++8POu=z6w>nizT`_Tc9%F7tX% z&-sv=*F&#CDgSUjzC|ekMjOe3RwMZJ{M@iHjPxq^2PhbQrTo>v|8gSuGdwZJQ`R|6lI7) zv*w=pm;|}|lq~!i)T(E6b(!8o;BFGA$R5^6K>Yg#-ho3>ymJHY2q<&x2Hr(xVsA7v zLvQ45wMRat{=i>Me2i<>8+p1EdF)2SR4PsC+;o$4e z1VzkZK8xof(`pU&HJ(X`=uWy)Bi@KLyp0qpUyQYN-48+W=VIP7HUAqlC3GL_)IEAd zBZTX3I`NkwL2>mGzHQj^b=2_g`kykbQ1#cpB48JHeMfP^i(XW*{3-gnF9}c8Yh{{` zXMlr2f4`;tCC0Np#UeI>4;CHoJoj$C-kLb=#Nd^@ zrN8q(`8IBqX(zs3&Tndk+xsy9ChSBzW5ujU7kd14j1v)ahC5nrz2z4;c@7QGsa zHVy3st1+NxL_fHiPva*bcycu#IPfR(uuiWWc&Dq8?v}q$_Nww>&G>@@RbP38#LOQu zuRDU@)?{N>-gLUP6Txgu!!6*W`^Skz_tAn4ipGH0aUYM8JlXvugzirgr|-jMS>aJR z2D*3es5c!29WNLKpM}X$knt~UOtMazb)ESa>dFR%x_U@hRzrMQ&9XJ9<^U)RweH>H zFQ_K|f@=JD0w*`ELAa7an{0DOk@ zCVyCnAl**Aw5GaKZ68@Hz2?;S0wXfiKb@E~5Hv6A41Q z)~P7{UvP`th1QQRM5aJ!C$3)pf?IJwM;1~I=~|?%kv@(z7HKh357KI+EszF~rXW?e zyA>}IFH-W=Af)j~CvJC(`c2yO*u4Ov0DOv+3Y-Ju`pw!w{>l!wNPkqjJTwOSiF@AC zqQr?UTC3P`3-6qsF>j{l+G{RNSClJ?-O6?1n@6=FP9xjpF>T;rnT5s`_^1Yp&O*Ke zzApG8@KLk+;cMLA>0;kwS{LUnJKf4`@#|ySjr{yhShhu*+>Al7&gCzX31N?G12bh7 z`nKYudM)}DXM1zMXb8ktf>DZw;Delx1Km$-lY*h-*@yjY*HY?e;}Wm(II2W0q&htlOr~TR3yp zlD?&GIZ!QSeIVP$QZ63as=eRlI7Eu@W#DVvS+kw#FS(UP;)^G=8{=z{rQt3iq#f}^ ziU+o6oozjbz}0fbpx%A^&=ks;cPnPh&|PljddSk0p)z(lrU^~s#o|*R*!eVyL$qkK zO&f01+x}_oB60sVEz#-qyOnFjbKA6MZ5B}!3&#j4b1PSgr=P@FHnQJ5sr5Ir?Vr+i z+DcFxMmKK5mfc1hvS9;tl||pzgkA&MZSlo*1*lDmij4)@xRALMFDrW4&^HINhzp8E z&ucxE~>&u)itBu?YyEKn#C7SYxgzrRc2#f^?bFluPoZ~l|@^=vgoy_n8t`j(;TMp zVyCGEcACaZ&m^|h0`#*iBknBJ`h{%22)`fD5}eCkb1PSiUkkN4yyi8x zf9A7VjLLt0-7U_o=RHOKbJ}6vbB|l(Jg;G!i_FpIwPdYok6X^r&j8SxryT`AYaRi6 z^LXd((Qg<)GE!RfF2P3uk-mxeY#x>iK0UMeS!07EK-&#$(S+Zs34bB#R{O}#%Cs8A zQ3rm+9kPk&PBxnM0Nre~7c_N(Rla)@KG78VEPn4Me4xjS#1WwVAQmT1+X{+>v!qPQ!D6IQFPE@G^^} z)sxJkL2j-5laP&ukURZSA<7nigLP=1deK$I~WG z(*F57wOH2rAMdyo8d;4C-r&6cUAHnrd|#rC#)X($3@Fvc@V@W4#qv@unO}pkt#R*DZ%&0hHbP8 zWTO3ATV9V$s$W~lr+ok!Kem#OAyenq;@xE*7+#%p=d2~OGZx)7*n@2&n9*gLSE~n; zI^#D0>1A4SSJysc;|M^3M-|V)Maw+17u~TCzPI`B|@3GN-e_(YROEc$2UY2R(pv=67qVW(+qS@iG7r%^bz z174dzEM{8oCNz1?lDD?W7OgdrC)zF_1DZyeB_A#M*mqk11q^!uV`Hu;&F#BgUl{vt ztE{#7NLnnc)Oy5@H$`qiN^0kQfmv3GDV>c>U8NQuTLuorf4fA)Th_)mv~i%A8~Y_X z&Hw0I+S>3w<+W~QIliIz&I2#Uw;bR3L-^|O1@Q&&9mH4b7T0{B^_qC)*T!7x=|O$S z(*(H!DcT%LZ}BWz;<=@PUJgFZTuaV2?)H74-Qe5;{&k}FK5eOXb-i&wom-Da?nC6r zL1ynhty^p{IMnZ#qDI>DfEE!SYOiWJhmAc{#$mUp{!p93k08^tTI(F^`o;)e&%(H& zC<59)vszPCKKO`R%-ydI(k?k-9GqtYDB7>-Jo_8BIJIA!aP?>4v_+v)NGWi$qsA7k z1yYIzx8VCLnE{X?hfr*VLgcVk9CiD1Khnmj{Dq@#QTwqrMXUMNP<`xMgrfrpB1y+! z)&VU!cKk6Tf`KDvG%+?E(E7zL2ZQ3~BS@*siBWq%n-E(8fY$g=koG`2=!n}t^b=H< zn10;2GZ>AOidx1c9CwTSPqlviv%#Q<^9WK0(v3*vy@=Tg2+AGzBJgP2PX!&HX?hP! z^HB)UA)>_zth-3tAf^7c*L3@5+Qs~u6K;RuXWBMr#~;tQX%nSfj*n7{o{T&h3EH1= WP}_NHTrB+m6MR^W?>T(r&;JL{bn5K@ diff --git a/x/compute/internal/types/codec.go b/x/compute/internal/types/codec.go index 86e8ea9ac..7524cfbf9 100644 --- a/x/compute/internal/types/codec.go +++ b/x/compute/internal/types/codec.go @@ -22,6 +22,7 @@ func RegisterInterfaces(registry types.InterfaceRegistry) { &MsgStoreCode{}, &MsgInstantiateContract{}, &MsgExecuteContract{}, + &MsgMigrateContract{}, ) } diff --git a/x/compute/internal/types/msg.pb.go b/x/compute/internal/types/msg.pb.go index 39238377c..bb806996b 100644 --- a/x/compute/internal/types/msg.pb.go +++ b/x/compute/internal/types/msg.pb.go @@ -646,59 +646,59 @@ func init() { func init() { proto.RegisterFile("secret/compute/v1beta1/msg.proto", fileDescriptor_6815433faf72a133) } var fileDescriptor_6815433faf72a133 = []byte{ - // 820 bytes of a gzipped FileDescriptorProto + // 832 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xbf, 0x8f, 0xe3, 0x44, - 0x14, 0x8e, 0xcf, 0xf9, 0xb1, 0x7e, 0x1b, 0xee, 0x56, 0xc3, 0x12, 0x7c, 0x41, 0x72, 0xa2, 0x40, - 0x11, 0xa1, 0x3b, 0xfb, 0x36, 0x48, 0x57, 0x1c, 0x55, 0x12, 0x7e, 0xa5, 0xf0, 0x15, 0x0e, 0x08, - 0x89, 0x26, 0x1a, 0xdb, 0x83, 0xe3, 0x5b, 0xc7, 0x0e, 0x9e, 0x09, 0xb9, 0x2d, 0x10, 0x2d, 0x25, - 0x05, 0x7f, 0x00, 0x35, 0x7f, 0xc9, 0xd1, 0x5d, 0x85, 0xb6, 0x0a, 0x28, 0xfb, 0x5f, 0x50, 0xa1, - 0x19, 0xff, 0x58, 0x6f, 0x48, 0x42, 0x58, 0xdd, 0x56, 0xf1, 0xcb, 0xbc, 0xf9, 0xde, 0xf7, 0xde, - 0xf7, 0xcd, 0xd8, 0xd0, 0xa6, 0xc4, 0x89, 0x09, 0x33, 0x9c, 0x68, 0x36, 0x5f, 0x30, 0x62, 0x7c, - 0x7f, 0x66, 0x13, 0x86, 0xcf, 0x8c, 0x19, 0xf5, 0xf4, 0x79, 0x1c, 0xb1, 0x08, 0x35, 0x92, 0x0c, - 0x3d, 0xcd, 0xd0, 0xd3, 0x8c, 0xe6, 0xa9, 0x17, 0x79, 0x91, 0x48, 0x31, 0xf8, 0x53, 0x92, 0xdd, - 0xd4, 0x9c, 0x88, 0xce, 0x22, 0x6a, 0xd8, 0x98, 0x5e, 0x83, 0x39, 0x91, 0x1f, 0x26, 0xeb, 0x9d, - 0xdf, 0x25, 0xa8, 0x9b, 0xd4, 0x1b, 0xb3, 0x28, 0x26, 0xc3, 0xc8, 0x25, 0x68, 0x04, 0x55, 0x4a, - 0x42, 0x97, 0xc4, 0xaa, 0xd4, 0x96, 0xba, 0xf5, 0xc1, 0xd9, 0xdf, 0xab, 0xd6, 0x63, 0xcf, 0x67, - 0xd3, 0x85, 0xcd, 0x4b, 0x1a, 0x29, 0x5e, 0xf2, 0xf3, 0x98, 0xba, 0xe7, 0x06, 0xbb, 0x98, 0x13, - 0xaa, 0xf7, 0x1d, 0xa7, 0xef, 0xba, 0x31, 0xa1, 0xd4, 0x4a, 0x01, 0xd0, 0x53, 0xb8, 0xbf, 0xc4, - 0x74, 0x36, 0xb1, 0x2f, 0x18, 0x99, 0x38, 0x91, 0x4b, 0xd4, 0x7b, 0x02, 0xf2, 0x64, 0xbd, 0x6a, - 0xd5, 0xbf, 0xee, 0x8f, 0xcd, 0xc1, 0x05, 0x13, 0x45, 0xad, 0x3a, 0xcf, 0xcb, 0x22, 0xd4, 0x80, - 0x2a, 0x8d, 0x16, 0xb1, 0x43, 0x54, 0xb9, 0x2d, 0x75, 0x15, 0x2b, 0x8d, 0x90, 0x0a, 0x35, 0x7b, - 0xe1, 0x07, 0x9c, 0x5b, 0x59, 0x2c, 0x64, 0xe1, 0xb3, 0xf2, 0x4f, 0xbf, 0xb6, 0x4a, 0x9d, 0x8f, - 0xe1, 0xb4, 0xd8, 0x8a, 0x45, 0xe8, 0x3c, 0x0a, 0x29, 0x41, 0xef, 0x43, 0x8d, 0x57, 0x9f, 0xf8, - 0xae, 0xe8, 0xa9, 0x3c, 0x80, 0xf5, 0xaa, 0x55, 0xe5, 0x29, 0xa3, 0x4f, 0xac, 0x2a, 0x5f, 0x1a, - 0xb9, 0x9d, 0x3f, 0x64, 0x68, 0x98, 0xd4, 0x1b, 0x85, 0x94, 0xe1, 0x90, 0xf9, 0x98, 0x73, 0x09, - 0x59, 0x8c, 0x1d, 0xf6, 0x26, 0x47, 0xf2, 0x08, 0x90, 0x83, 0x83, 0xc0, 0xc6, 0xce, 0xb9, 0x98, - 0xc8, 0x64, 0x8a, 0xe9, 0x54, 0x8c, 0x45, 0xb1, 0x4e, 0xb2, 0x15, 0xce, 0xec, 0x0b, 0x4c, 0xa7, - 0x45, 0xe2, 0xf2, 0x2e, 0xe2, 0xe8, 0x14, 0x2a, 0x01, 0xb6, 0x49, 0x90, 0xce, 0x24, 0x09, 0xd0, - 0x43, 0x38, 0xf2, 0x43, 0x9f, 0x4d, 0x66, 0xd4, 0x53, 0x2b, 0x9c, 0xb5, 0x55, 0xe3, 0xb1, 0x49, - 0x3d, 0xf4, 0x02, 0x40, 0x2c, 0x7d, 0xbb, 0x08, 0x5d, 0xaa, 0x56, 0xdb, 0x72, 0xf7, 0xb8, 0xf7, - 0x50, 0x4f, 0xd8, 0xeb, 0xdc, 0x27, 0x99, 0xa5, 0xf4, 0x61, 0xe4, 0x87, 0x83, 0x27, 0xaf, 0x56, - 0xad, 0xd2, 0x6f, 0x7f, 0xb6, 0xba, 0x07, 0x74, 0xcc, 0x37, 0x50, 0x4b, 0xe1, 0xf0, 0x9f, 0x71, - 0x74, 0xd4, 0x83, 0x7a, 0xde, 0x2f, 0xf5, 0x3d, 0xb5, 0x26, 0x06, 0xf8, 0x60, 0xbd, 0x6a, 0x1d, - 0x0f, 0xd3, 0xff, 0xc7, 0xbe, 0x67, 0x1d, 0x3b, 0xd7, 0x01, 0xfa, 0x1c, 0x2a, 0xd8, 0x9d, 0xf9, - 0xa1, 0x7a, 0x74, 0xdb, 0x69, 0x27, 0xfb, 0x53, 0x57, 0x3c, 0x07, 0x6d, 0xbb, 0xae, 0xb9, 0x3f, - 0x54, 0xa8, 0xe1, 0x64, 0xa7, 0x10, 0x58, 0xb1, 0xb2, 0x10, 0x21, 0x28, 0xbb, 0x98, 0xe1, 0xc4, - 0xb7, 0x96, 0x78, 0xee, 0xfc, 0x22, 0x03, 0x32, 0xa9, 0xf7, 0xe9, 0x4b, 0xe2, 0x2c, 0xee, 0xc6, - 0x24, 0x26, 0x1c, 0x39, 0x29, 0x6c, 0x7a, 0x62, 0x6e, 0x01, 0x96, 0x43, 0xa0, 0x13, 0x90, 0xb9, - 0x0b, 0x64, 0xd1, 0x03, 0x7f, 0xdc, 0xe1, 0xc2, 0xf2, 0x0e, 0x17, 0xbe, 0x00, 0xa0, 0x24, 0xcc, - 0xfc, 0x52, 0xb9, 0x03, 0xbf, 0x70, 0xf8, 0xed, 0x7e, 0xa9, 0xfe, 0xb7, 0x5f, 0x52, 0x99, 0x9f, - 0x40, 0xf3, 0xdf, 0xaa, 0xe4, 0x12, 0x67, 0x42, 0x4a, 0x05, 0x21, 0x7f, 0x14, 0x3a, 0x9a, 0xbe, - 0x17, 0x17, 0x0f, 0x7b, 0xe3, 0x86, 0x8e, 0x4a, 0x2e, 0x4a, 0x73, 0x43, 0x14, 0xa5, 0x30, 0xe1, - 0x83, 0xce, 0x69, 0x2a, 0x43, 0x39, 0x97, 0x21, 0xa5, 0xbc, 0x41, 0x60, 0x2f, 0x65, 0x0c, 0xf7, - 0x4d, 0xea, 0x7d, 0x35, 0x77, 0x31, 0x23, 0x7d, 0xee, 0xf1, 0x9d, 0x74, 0xdf, 0x03, 0x25, 0x24, - 0xcb, 0x49, 0x72, 0x90, 0x52, 0xbe, 0x21, 0x59, 0x26, 0x9b, 0x8a, 0xbd, 0xc8, 0x37, 0x7b, 0xe9, - 0xa8, 0xe2, 0x1a, 0x2c, 0x94, 0xc8, 0x08, 0x75, 0x86, 0xf0, 0x96, 0x49, 0xbd, 0x61, 0x40, 0x70, - 0xbc, 0xbf, 0xf6, 0x3e, 0xf8, 0x77, 0xe1, 0x9d, 0x1b, 0x20, 0x19, 0x7a, 0xef, 0xf2, 0x1e, 0xc8, - 0xfc, 0x76, 0x9a, 0x80, 0x72, 0xfd, 0x32, 0xfa, 0x40, 0xdf, 0xfe, 0xb2, 0xd3, 0x8b, 0xf7, 0x7c, - 0xf3, 0xd1, 0x21, 0x59, 0xf9, 0x5c, 0x7f, 0x80, 0xb7, 0xb7, 0x5d, 0xf2, 0xfa, 0x1e, 0x90, 0x2d, - 0xf9, 0xcd, 0xa7, 0xff, 0x2f, 0x3f, 0x2f, 0xff, 0x1d, 0x3c, 0xd8, 0xbc, 0x3a, 0x3e, 0xdc, 0x03, - 0xb5, 0x91, 0xdb, 0xec, 0x1d, 0x9e, 0x9b, 0x95, 0x1c, 0x7c, 0xf9, 0x6a, 0xad, 0x49, 0xaf, 0xd7, - 0x9a, 0xf4, 0xd7, 0x5a, 0x93, 0x7e, 0xbe, 0xd2, 0x4a, 0xaf, 0xaf, 0xb4, 0xd2, 0xe5, 0x95, 0x56, - 0xfa, 0xe6, 0x59, 0xe1, 0x8c, 0x52, 0x27, 0x66, 0x01, 0xb6, 0xa9, 0x31, 0x16, 0x05, 0x9e, 0x13, - 0xb6, 0x8c, 0xe2, 0x73, 0xe3, 0x65, 0xfe, 0x29, 0xe2, 0x87, 0x8c, 0xc4, 0x21, 0x0e, 0x92, 0xb3, - 0x6b, 0x57, 0xc5, 0x07, 0xc4, 0x47, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0xbb, 0x3e, 0x4b, 0x85, - 0xb2, 0x08, 0x00, 0x00, + 0x14, 0x8e, 0x71, 0x7e, 0xac, 0xdf, 0x86, 0xbb, 0xd5, 0xb0, 0x04, 0x5f, 0x90, 0x9c, 0x28, 0x50, + 0x44, 0xe8, 0xce, 0xbe, 0x0d, 0xd2, 0x15, 0x47, 0x95, 0x84, 0x5f, 0x29, 0x7c, 0x85, 0x03, 0x42, + 0xa2, 0x89, 0xc6, 0xf6, 0xe0, 0xf8, 0xd6, 0xb1, 0x83, 0x67, 0x42, 0x6e, 0x0b, 0x44, 0x4b, 0x49, + 0xc1, 0x1f, 0x40, 0xcd, 0x5f, 0xb2, 0x88, 0x66, 0x2b, 0x44, 0x15, 0x50, 0xf6, 0xbf, 0xa0, 0x42, + 0x33, 0xfe, 0xb1, 0xde, 0x90, 0x84, 0xb0, 0x62, 0xab, 0x78, 0x32, 0x6f, 0xbe, 0xf7, 0xbd, 0xf7, + 0x7d, 0xf3, 0x6c, 0x68, 0x53, 0xe2, 0xc4, 0x84, 0x19, 0x4e, 0x34, 0x9b, 0x2f, 0x18, 0x31, 0xbe, + 0x39, 0xb3, 0x09, 0xc3, 0x67, 0xc6, 0x8c, 0x7a, 0xfa, 0x3c, 0x8e, 0x58, 0x84, 0x1a, 0x49, 0x84, + 0x9e, 0x46, 0xe8, 0x69, 0x44, 0xf3, 0xd4, 0x8b, 0xbc, 0x48, 0x84, 0x18, 0xfc, 0x29, 0x89, 0x6e, + 0x6a, 0x4e, 0x44, 0x67, 0x11, 0x35, 0x6c, 0x4c, 0x6f, 0xc0, 0x9c, 0xc8, 0x0f, 0x93, 0xfd, 0xce, + 0x2f, 0x12, 0xd4, 0x4d, 0xea, 0x8d, 0x59, 0x14, 0x93, 0x61, 0xe4, 0x12, 0x34, 0x82, 0x2a, 0x25, + 0xa1, 0x4b, 0x62, 0x55, 0x6a, 0x4b, 0xdd, 0xfa, 0xe0, 0xec, 0xaf, 0x55, 0xeb, 0x89, 0xe7, 0xb3, + 0xe9, 0xc2, 0xe6, 0x29, 0x8d, 0x14, 0x2f, 0xf9, 0x79, 0x42, 0xdd, 0x73, 0x83, 0x5d, 0xcc, 0x09, + 0xd5, 0xfb, 0x8e, 0xd3, 0x77, 0xdd, 0x98, 0x50, 0x6a, 0xa5, 0x00, 0xe8, 0x19, 0x3c, 0x58, 0x62, + 0x3a, 0x9b, 0xd8, 0x17, 0x8c, 0x4c, 0x9c, 0xc8, 0x25, 0xea, 0x6b, 0x02, 0xf2, 0x64, 0xbd, 0x6a, + 0xd5, 0xbf, 0xe8, 0x8f, 0xcd, 0xc1, 0x05, 0x13, 0x49, 0xad, 0x3a, 0x8f, 0xcb, 0x56, 0xa8, 0x01, + 0x55, 0x1a, 0x2d, 0x62, 0x87, 0xa8, 0x72, 0x5b, 0xea, 0x2a, 0x56, 0xba, 0x42, 0x2a, 0xd4, 0xec, + 0x85, 0x1f, 0x70, 0x6e, 0x65, 0xb1, 0x91, 0x2d, 0x9f, 0x97, 0xbf, 0xff, 0xa9, 0x55, 0xea, 0x7c, + 0x00, 0xa7, 0xc5, 0x52, 0x2c, 0x42, 0xe7, 0x51, 0x48, 0x09, 0x7a, 0x07, 0x6a, 0x3c, 0xfb, 0xc4, + 0x77, 0x45, 0x4d, 0xe5, 0x01, 0xac, 0x57, 0xad, 0x2a, 0x0f, 0x19, 0x7d, 0x68, 0x55, 0xf9, 0xd6, + 0xc8, 0xed, 0xfc, 0x26, 0x43, 0xc3, 0xa4, 0xde, 0x28, 0xa4, 0x0c, 0x87, 0xcc, 0xc7, 0x9c, 0x4b, + 0xc8, 0x62, 0xec, 0xb0, 0xff, 0xb3, 0x25, 0x8f, 0x01, 0x39, 0x38, 0x08, 0x6c, 0xec, 0x9c, 0x8b, + 0x8e, 0x4c, 0xa6, 0x98, 0x4e, 0x45, 0x5b, 0x14, 0xeb, 0x24, 0xdb, 0xe1, 0xcc, 0x3e, 0xc5, 0x74, + 0x5a, 0x24, 0x2e, 0xef, 0x22, 0x8e, 0x4e, 0xa1, 0x12, 0x60, 0x9b, 0x04, 0x69, 0x4f, 0x92, 0x05, + 0x7a, 0x04, 0x47, 0x7e, 0xe8, 0xb3, 0xc9, 0x8c, 0x7a, 0x6a, 0x85, 0xb3, 0xb6, 0x6a, 0x7c, 0x6d, + 0x52, 0x0f, 0xbd, 0x04, 0x10, 0x5b, 0x5f, 0x2d, 0x42, 0x97, 0xaa, 0xd5, 0xb6, 0xdc, 0x3d, 0xee, + 0x3d, 0xd2, 0x13, 0xf6, 0x3a, 0xf7, 0x49, 0x66, 0x29, 0x7d, 0x18, 0xf9, 0xe1, 0xe0, 0xe9, 0xe5, + 0xaa, 0x55, 0xfa, 0xf9, 0x8f, 0x56, 0xf7, 0x80, 0x8a, 0xf9, 0x01, 0x6a, 0x29, 0x1c, 0xfe, 0x63, + 0x8e, 0x8e, 0x7a, 0x50, 0xcf, 0xeb, 0xa5, 0xbe, 0xa7, 0xd6, 0x44, 0x03, 0x1f, 0xae, 0x57, 0xad, + 0xe3, 0x61, 0xfa, 0xff, 0xd8, 0xf7, 0xac, 0x63, 0xe7, 0x66, 0x81, 0x3e, 0x81, 0x0a, 0x76, 0x67, + 0x7e, 0xa8, 0x1e, 0xdd, 0xb5, 0xdb, 0xc9, 0xf9, 0xd4, 0x15, 0x2f, 0x40, 0xdb, 0xae, 0x6b, 0xee, + 0x0f, 0x15, 0x6a, 0x38, 0x39, 0x29, 0x04, 0x56, 0xac, 0x6c, 0x89, 0x10, 0x94, 0x5d, 0xcc, 0x70, + 0xe2, 0x5b, 0x4b, 0x3c, 0x77, 0x7e, 0x94, 0x01, 0x99, 0xd4, 0xfb, 0xe8, 0x15, 0x71, 0x16, 0xf7, + 0x63, 0x12, 0x13, 0x8e, 0x9c, 0x14, 0x36, 0xbd, 0x31, 0x77, 0x00, 0xcb, 0x21, 0xd0, 0x09, 0xc8, + 0xdc, 0x05, 0xb2, 0xa8, 0x81, 0x3f, 0xee, 0x70, 0x61, 0x79, 0x87, 0x0b, 0x5f, 0x02, 0x50, 0x12, + 0x66, 0x7e, 0xa9, 0xdc, 0x83, 0x5f, 0x38, 0xfc, 0x76, 0xbf, 0x54, 0xff, 0xdd, 0x2f, 0xa9, 0xcc, + 0x4f, 0xa1, 0xf9, 0x4f, 0x55, 0x72, 0x89, 0x33, 0x21, 0xa5, 0x82, 0x90, 0xdf, 0x09, 0x1d, 0x4d, + 0xdf, 0x8b, 0x8b, 0x97, 0xbd, 0x71, 0x4b, 0x47, 0x25, 0x17, 0xa5, 0xb9, 0x21, 0x8a, 0x52, 0xe8, + 0xf0, 0x41, 0xf7, 0x34, 0x95, 0xa1, 0x9c, 0xcb, 0x90, 0x52, 0xde, 0x20, 0xb0, 0x97, 0x32, 0x86, + 0x07, 0x26, 0xf5, 0x3e, 0x9f, 0xbb, 0x98, 0x91, 0x3e, 0xf7, 0xf8, 0x4e, 0xba, 0x6f, 0x83, 0x12, + 0x92, 0xe5, 0x24, 0xb9, 0x48, 0x29, 0xdf, 0x90, 0x2c, 0x93, 0x43, 0xc5, 0x5a, 0xe4, 0xdb, 0xb5, + 0x74, 0x54, 0x31, 0x06, 0x0b, 0x29, 0x32, 0x42, 0x9d, 0x21, 0xbc, 0x6e, 0x52, 0x6f, 0x18, 0x10, + 0x1c, 0xef, 0xcf, 0xbd, 0x0f, 0xfe, 0x2d, 0x78, 0xf3, 0x16, 0x48, 0x86, 0xde, 0xfb, 0x55, 0x06, + 0x99, 0x4f, 0xa7, 0x09, 0x28, 0x37, 0x2f, 0xa3, 0x77, 0xf5, 0xed, 0x2f, 0x3b, 0xbd, 0x38, 0xe7, + 0x9b, 0x8f, 0x0f, 0x89, 0xca, 0xfb, 0xfa, 0x2d, 0xbc, 0xb1, 0x6d, 0xc8, 0xeb, 0x7b, 0x40, 0xb6, + 0xc4, 0x37, 0x9f, 0xfd, 0xb7, 0xf8, 0x3c, 0xfd, 0xd7, 0xf0, 0x70, 0x73, 0x74, 0xbc, 0xb7, 0x07, + 0x6a, 0x23, 0xb6, 0xd9, 0x3b, 0x3c, 0xb6, 0x98, 0x72, 0xd3, 0xe5, 0xfb, 0x52, 0x6e, 0xc4, 0xee, + 0x4d, 0xb9, 0xc3, 0xbc, 0x83, 0xcf, 0x2e, 0xd7, 0x9a, 0x74, 0xb5, 0xd6, 0xa4, 0x3f, 0xd7, 0x9a, + 0xf4, 0xc3, 0xb5, 0x56, 0xba, 0xba, 0xd6, 0x4a, 0xbf, 0x5f, 0x6b, 0xa5, 0x2f, 0x9f, 0x17, 0xc6, + 0x02, 0x75, 0x62, 0x16, 0x60, 0x9b, 0x1a, 0x63, 0x91, 0xe0, 0x05, 0x61, 0xcb, 0x28, 0x3e, 0x37, + 0x5e, 0xe5, 0x5f, 0x3f, 0x7e, 0xc8, 0x48, 0x1c, 0xe2, 0x20, 0x19, 0x17, 0x76, 0x55, 0x7c, 0xb3, + 0xbc, 0xff, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x6c, 0x4a, 0x85, 0xf4, 0x25, 0x09, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -719,6 +719,7 @@ type MsgClient interface { InstantiateContract(ctx context.Context, in *MsgInstantiateContract, opts ...grpc.CallOption) (*MsgInstantiateContractResponse, error) // Execute submits the given message data to a smart contract ExecuteContract(ctx context.Context, in *MsgExecuteContract, opts ...grpc.CallOption) (*MsgExecuteContractResponse, error) + MigrateContract(ctx context.Context, in *MsgMigrateContract, opts ...grpc.CallOption) (*MsgMigrateContractResponse, error) } type msgClient struct { @@ -756,6 +757,15 @@ func (c *msgClient) ExecuteContract(ctx context.Context, in *MsgExecuteContract, return out, nil } +func (c *msgClient) MigrateContract(ctx context.Context, in *MsgMigrateContract, opts ...grpc.CallOption) (*MsgMigrateContractResponse, error) { + out := new(MsgMigrateContractResponse) + err := c.cc.Invoke(ctx, "/secret.compute.v1beta1.Msg/MigrateContract", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // MsgServer is the server API for Msg service. type MsgServer interface { // StoreCode to submit Wasm code to the system @@ -764,6 +774,7 @@ type MsgServer interface { InstantiateContract(context.Context, *MsgInstantiateContract) (*MsgInstantiateContractResponse, error) // Execute submits the given message data to a smart contract ExecuteContract(context.Context, *MsgExecuteContract) (*MsgExecuteContractResponse, error) + MigrateContract(context.Context, *MsgMigrateContract) (*MsgMigrateContractResponse, error) } // UnimplementedMsgServer can be embedded to have forward compatible implementations. @@ -779,6 +790,9 @@ func (*UnimplementedMsgServer) InstantiateContract(ctx context.Context, req *Msg func (*UnimplementedMsgServer) ExecuteContract(ctx context.Context, req *MsgExecuteContract) (*MsgExecuteContractResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ExecuteContract not implemented") } +func (*UnimplementedMsgServer) MigrateContract(ctx context.Context, req *MsgMigrateContract) (*MsgMigrateContractResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method MigrateContract not implemented") +} func RegisterMsgServer(s grpc1.Server, srv MsgServer) { s.RegisterService(&_Msg_serviceDesc, srv) @@ -838,6 +852,24 @@ func _Msg_ExecuteContract_Handler(srv interface{}, ctx context.Context, dec func return interceptor(ctx, in, info, handler) } +func _Msg_MigrateContract_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgMigrateContract) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).MigrateContract(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/secret.compute.v1beta1.Msg/MigrateContract", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).MigrateContract(ctx, req.(*MsgMigrateContract)) + } + return interceptor(ctx, in, info, handler) +} + var _Msg_serviceDesc = grpc.ServiceDesc{ ServiceName: "secret.compute.v1beta1.Msg", HandlerType: (*MsgServer)(nil), @@ -854,6 +886,10 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "ExecuteContract", Handler: _Msg_ExecuteContract_Handler, }, + { + MethodName: "MigrateContract", + Handler: _Msg_MigrateContract_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "secret/compute/v1beta1/msg.proto", diff --git a/x/compute/internal/types/types.go b/x/compute/internal/types/types.go index e156a9d45..9bb6a0585 100644 --- a/x/compute/internal/types/types.go +++ b/x/compute/internal/types/types.go @@ -58,11 +58,12 @@ func NewCodeInfo(codeHash []byte, creator sdk.AccAddress, source string, builder // NewContractInfo creates a new instance of a given WASM contract info func NewContractInfo(codeID uint64, creator sdk.AccAddress, admin sdk.AccAddress, adminProof []byte, label string, createdAt *AbsoluteTxPosition) ContractInfo { return ContractInfo{ - CodeID: codeID, - Creator: creator, - Label: label, - Created: createdAt, - Admin: admin, + CodeID: codeID, + Creator: creator, + Label: label, + Created: createdAt, + Admin: admin, + AdminProof: adminProof, } } @@ -147,11 +148,15 @@ func NewEnv(ctx sdk.Context, creator sdk.AccAddress, deposit sdk.Coins, contract if contractKey != nil { env.Key = &wasmTypes.ContractKey{ - Key: contractKey.Key, - Original: wasmTypes.ContractKeyWithProof{ + Key: contractKey.Key, + Original: nil, + } + + if contractKey.Original != nil { + env.Key.Original = &wasmTypes.ContractKeyWithProof{ Proof: contractKey.Original.Proof, - Key: contractKey.Original.Proof, - }, + Key: contractKey.Original.Key, + } } } From be73d999047ff696b112ea1d7d29ff49b293fdd1 Mon Sep 17 00:00:00 2001 From: Itzik Grossman Date: Tue, 23 May 2023 20:56:22 +0300 Subject: [PATCH 010/164] Tests are back online boys --- x/compute/internal/keeper/keeper.go | 10 ---------- x/compute/internal/keeper/keeper_test.go | 2 +- .../internal/keeper/secret_contracts_exec_test.go | 13 +++++-------- .../internal/keeper/secret_contracts_utils_test.go | 1 - 4 files changed, 6 insertions(+), 20 deletions(-) diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index eb5a08da0..96dfbc4c6 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -426,9 +426,6 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator sdk.AccAddre response, key, adminProof, gasUsed, err := k.wasmer.Instantiate(codeInfo.CodeHash, env, initMsg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, verificationInfo, admin) consumeGas(ctx, gasUsed) - println("Got admin proof: *******************************", hex.EncodeToString(adminProof)) - println("Got new key: *******************************", hex.EncodeToString(key)) - if err != nil { switch res := response.(type) { //nolint:gocritic case v1wasmTypes.DataWithInternalReplyInfo: @@ -568,13 +565,6 @@ func (k Keeper) Execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller return nil, err } - println("Running with contract key: ******************************* ", hex.EncodeToString(contractKey.Key)) - - if contractKey.Original != nil { - println("Running with OG contract key: ******************************* ", hex.EncodeToString(contractKey.Original.Key)) - println("Running with OG Proof: ******************************* ", hex.EncodeToString(contractKey.Original.Proof)) - } - env := types.NewEnv(ctx, caller, coins, contractAddress, &contractKey, random) // prepare querier diff --git a/x/compute/internal/keeper/keeper_test.go b/x/compute/internal/keeper/keeper_test.go index 232ddfc96..ccb27f76b 100644 --- a/x/compute/internal/keeper/keeper_test.go +++ b/x/compute/internal/keeper/keeper_test.go @@ -299,7 +299,7 @@ func TestInstantiate(t *testing.T) { // gas can change +- 10% before we start failing, though maybe for consensus we should check a constant amount gasAfter := ctx.GasMeter().GasConsumed() require.Greater(t, gasAfter-gasBefore, types.InstanceCost) - require.Less(t, gasAfter-gasBefore, types.InstanceCost+8000) + require.Less(t, gasAfter-gasBefore, types.InstanceCost+10_000) // ensure it is stored properly info := keeper.GetContractInfo(ctx, contractAddr) diff --git a/x/compute/internal/keeper/secret_contracts_exec_test.go b/x/compute/internal/keeper/secret_contracts_exec_test.go index 036935afd..098add615 100644 --- a/x/compute/internal/keeper/secret_contracts_exec_test.go +++ b/x/compute/internal/keeper/secret_contracts_exec_test.go @@ -304,7 +304,7 @@ func TestEnv(t *testing.T) { { Key: "env", Value: fmt.Sprintf( - `{"block":{"height":%d,"time":%d,"chain_id":"%s"},"message":{"sender":"%s","sent_funds":[{"denom":"denom","amount":"1"}]},"contract":{"address":"%s"},"contract_key":"","contract_code_hash":"%s"}`, + `{"block":{"height":%d,"time":%d,"chain_id":"%s"},"message":{"sender":"%s","sent_funds":[{"denom":"denom","amount":"1"}]},"contract":{"address":"%s"},"contract_key":null,"contract_code_hash":"%s"}`, ctx.BlockHeight(), // env.block.time is seconds since unix epoch ctx.BlockTime().Unix(), @@ -351,8 +351,6 @@ func TestEnv(t *testing.T) { // require.NotEqual(t, firstRandom, actualMessageInfo.Random) } else { - contractKey, _ := keeper.GetContractKey(ctx, contractAddress) - requireEvents(t, []ContractEvent{ { @@ -360,14 +358,13 @@ func TestEnv(t *testing.T) { { Key: "env", Value: fmt.Sprintf( - `{"block":{"height":%d,"time":%d,"chain_id":"%s"},"message":{"sender":"%s","sent_funds":[{"denom":"denom","amount":"1"}]},"contract":{"address":"%s"},"contract_key":"%s","contract_code_hash":"%s"}`, + `{"block":{"height":%d,"time":%d,"chain_id":"%s"},"message":{"sender":"%s","sent_funds":[{"denom":"denom","amount":"1"}]},"contract":{"address":"%s"},"contract_key":null,"contract_code_hash":"%s"}`, ctx.BlockHeight(), // env.block.time is seconds since unix epoch ctx.BlockTime().Unix(), ctx.ChainID(), walletA.String(), contractAddress.String(), - base64.StdEncoding.EncodeToString(contractKey.Key), calcCodeHash(testContract.WasmFilePath), ), }, @@ -2295,7 +2292,7 @@ func TestCheckGas(t *testing.T) { require.Empty(t, initErr) // 995 is the sum of all the overhead that goes into a contract call beyond the base cost (reading keys, calculations, etc) - baseContractUsage := types.InstanceCost + 995 + baseContractUsage := types.InstanceCost + 1053 _, _, _, events, baseGasUsed, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"check_gas":{}}`, true, true, defaultGasForTests, 0) require.Empty(t, err) @@ -2305,7 +2302,7 @@ func TestCheckGas(t *testing.T) { gasUsed, err2 := strconv.ParseUint(execEvent[1].Value, 10, 64) require.Empty(t, err2) - require.Equal(t, gasUsed+1, baseGasUsed-baseContractUsage) + require.Equal(t, baseGasUsed-baseContractUsage, gasUsed+1) } func TestConsumeExact(t *testing.T) { @@ -2314,7 +2311,7 @@ func TestConsumeExact(t *testing.T) { require.Empty(t, initErr) // not sure where the 16 extra gas comes vs the previous check_gas test, but it makes everything play nice, so.... - baseContractUsage := types.InstanceCost + 995 - 16 + baseContractUsage := types.InstanceCost + 1053 - 16 for _, test := range []struct { description string diff --git a/x/compute/internal/keeper/secret_contracts_utils_test.go b/x/compute/internal/keeper/secret_contracts_utils_test.go index 24e816d9f..2d98aa7f0 100644 --- a/x/compute/internal/keeper/secret_contracts_utils_test.go +++ b/x/compute/internal/keeper/secret_contracts_utils_test.go @@ -546,7 +546,6 @@ func execTxBuilderImpl( execResult, err := keeper.Execute(ctx, contractAddress, txSender, msg, coins, nil) gasAfter := ctx.GasMeter().GasConsumed() gasUsed := gasAfter - gasBefore - require.NoError(t, err) if wasmCallCount < 0 { // default, just check that at least 1 call happened From 652a3a3a1550f58fb6186b540aa6c0193de76dc7 Mon Sep 17 00:00:00 2001 From: Itzik Grossman Date: Tue, 23 May 2023 21:07:36 +0300 Subject: [PATCH 011/164] forgot to commit the contracts for the migrate test --- .../keeper/testdata/migrate_contract_v1.wasm | Bin 0 -> 140758 bytes .../keeper/testdata/migrate_contract_v2.wasm | Bin 0 -> 143630 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100755 x/compute/internal/keeper/testdata/migrate_contract_v1.wasm create mode 100755 x/compute/internal/keeper/testdata/migrate_contract_v2.wasm diff --git a/x/compute/internal/keeper/testdata/migrate_contract_v1.wasm b/x/compute/internal/keeper/testdata/migrate_contract_v1.wasm new file mode 100755 index 0000000000000000000000000000000000000000..38b774add2736cc0a61c6bf83ce5894684f56143 GIT binary patch literal 140758 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 Sjn4T!?Ay=tdoMrPqW>@PFhyMe literal 0 HcmV?d00001 From fbe8ccd90e7bea567784b7dc7de0afd057663308 Mon Sep 17 00:00:00 2001 From: Itzik Grossman Date: Wed, 24 May 2023 14:12:57 +0300 Subject: [PATCH 012/164] Deriving admin proof from contract_key Added check for admin == sender in keeper Added tests to check that storage can be read post-migration Added test for trying to migrate with different address --- .../migration/contract-v1/src/contract.rs | 10 +++++- .../migration/contract-v2/src/contract.rs | 26 ++++++++++++++ .../migration/contract-v2/src/msg.rs | 1 + .../src/contract_operations.rs | 24 +++++++------ .../contract-engine/src/external/ecalls.rs | 2 +- cosmwasm/enclaves/shared/crypto/src/lib.rs | 2 +- x/compute/internal/keeper/keeper.go | 13 +++---- .../keeper/secret_contracts_migrate_test.go | 34 ++++++++++++++++++ .../keeper/secret_contracts_utils_test.go | 2 +- .../keeper/testdata/migrate_contract_v1.wasm | Bin 140758 -> 141215 bytes .../keeper/testdata/migrate_contract_v2.wasm | Bin 143630 -> 145767 bytes 11 files changed, 93 insertions(+), 21 deletions(-) diff --git a/cosmwasm/contracts/v1/compute-tests/migration/contract-v1/src/contract.rs b/cosmwasm/contracts/v1/compute-tests/migration/contract-v1/src/contract.rs index 197d54d69..fe5760742 100644 --- a/cosmwasm/contracts/v1/compute-tests/migration/contract-v1/src/contract.rs +++ b/cosmwasm/contracts/v1/compute-tests/migration/contract-v1/src/contract.rs @@ -3,11 +3,12 @@ use cosmwasm_std::{entry_point, DepsMut, Env, MessageInfo, Response, StdResult}; #[entry_point] pub fn instantiate( - _deps: DepsMut, + deps: DepsMut, _env: Env, _info: MessageInfo, _msg: InstantiateMsg, ) -> StdResult { + write_to_storage(deps)?; Ok(Response::default()) } @@ -22,3 +23,10 @@ pub fn execute( ExecuteMsg::Test {} => Ok(Response::default()), } } + +#[allow(dead_code)] +pub fn write_to_storage(deps: DepsMut) -> StdResult<()> { + deps.storage.set(b"test.key", &1u64.to_be_bytes()); + + Ok(()) +} diff --git a/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/src/contract.rs b/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/src/contract.rs index 15703f81f..c493b26cd 100644 --- a/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/src/contract.rs +++ b/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/src/contract.rs @@ -20,6 +20,17 @@ pub fn execute( ) -> StdResult { match msg { ExecuteMsg::NewFunction {} => Ok(Response::default()), + + ExecuteMsg::NewFunctionWithStorage {} => { + let mut x = read_storage(&deps)?; + + // let mut resp = Response::new(); + // + // resp.x += 1; + x += 1; + write_to_storage(deps, x)?; + Ok(Response::default()) + } } } @@ -29,3 +40,18 @@ pub fn migrate(_deps: DepsMut, _env: Env, msg: MigrateMsg) -> StdResult Ok(Response::default()), } } + +pub fn read_storage(deps: &DepsMut) -> StdResult { + let x = deps.storage.get(b"test.key").unwrap_or(vec![]); + + let mut y = [0u8; 8]; + y.copy_from_slice(&x); + Ok(u64::from_be_bytes(y)) +} + +#[allow(dead_code)] +pub fn write_to_storage(deps: DepsMut, value: u64) -> StdResult<()> { + deps.storage.set(b"test.key", &value.to_be_bytes()); + + Ok(()) +} diff --git a/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/src/msg.rs b/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/src/msg.rs index effb5c93a..e4faa4d78 100644 --- a/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/src/msg.rs +++ b/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/src/msg.rs @@ -10,6 +10,7 @@ pub enum InstantiateMsg { #[serde(rename_all = "snake_case")] pub enum ExecuteMsg { NewFunction {}, + NewFunctionWithStorage {}, } #[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, JsonSchema)] diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index a76a8e377..489a58857 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -9,7 +9,7 @@ use cw_types_v010::encoding::Binary; use cw_types_v010::types::CanonicalAddr; use enclave_cosmos_types::types::{ContractCode, HandleType, SigInfo}; -use enclave_crypto::{sha_256, Ed25519PublicKey}; +use enclave_crypto::{sha_256, Ed25519PublicKey, KEY_MANAGER}; use enclave_ffi_types::{Ctx, EnclaveError}; use log::*; @@ -55,10 +55,10 @@ we need to allocate memory regions inside the VM's instance and copy `env` & `msg` into those memory regions inside the VM's instance. */ -fn generate_admin_signature(admin: &[u8], code_hash: &[u8]) -> [u8; enclave_crypto::HASH_SIZE] { +fn generate_admin_signature(admin: &[u8], contract_key: &[u8]) -> [u8; enclave_crypto::HASH_SIZE] { let mut data_to_hash = vec![]; data_to_hash.extend_from_slice(admin); - data_to_hash.extend_from_slice(code_hash); + data_to_hash.extend_from_slice(contract_key); sha_256(&data_to_hash) } @@ -106,8 +106,6 @@ pub fn init( verify_block_info(&base_env)?; } - let admin_sig = generate_admin_signature(admin, &contract_hash); - // let duration = start.elapsed(); // trace!("Time elapsed in extract_base_env is: {:?}", duration); let query_depth = extract_query_depth(env)?; @@ -127,6 +125,8 @@ pub fn init( &canonical_contract_address, )?; + let admin_sig = generate_admin_signature(&canonical_sender_address.0 .0, &contract_key); + let parsed_sig_info: SigInfo = extract_sig_info(sig_info)?; let secret_msg = SecretMessage::from_slice(msg)?; @@ -279,12 +279,6 @@ pub fn migrate( verify_block_info(&base_env)?; } - let admin_sig = generate_admin_signature(admin, &contract_hash); - - if &admin_sig != admin_proof { - error!("Failed to validate admin signature for migrate"); - } - // let duration = start.elapsed(); // trace!("Time elapsed in extract_base_env is: {:?}", duration); let query_depth = extract_query_depth(env)?; @@ -306,6 +300,14 @@ pub fn migrate( let og_contract_key = base_env.get_contract_key()?; + let admin_sig = generate_admin_signature(&canonical_sender_address.0 .0, &og_contract_key); + + if &admin_sig != admin_proof { + error!("Failed to validate admin signature for migrate"); + return Err(EnclaveError::ValidationFailure); + } + debug!("validated migration proof successfully"); + let contract_key_proof = generate_contract_key_proof( &canonical_sender_address.0 .0, &contract_code.hash(), diff --git a/cosmwasm/enclaves/shared/contract-engine/src/external/ecalls.rs b/cosmwasm/enclaves/shared/contract-engine/src/external/ecalls.rs index 202b49219..68c133eb8 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/external/ecalls.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/external/ecalls.rs @@ -482,7 +482,7 @@ pub unsafe extern "C" fn ecall_migrate( err: EnclaveError::OutOfMemory, } } else { - error!("Call ecall_handle panicked unexpectedly!"); + error!("Call ecall_migrate panicked unexpectedly!"); MigrateResult::Failure { err: EnclaveError::Panic, } diff --git a/cosmwasm/enclaves/shared/crypto/src/lib.rs b/cosmwasm/enclaves/shared/crypto/src/lib.rs index d7e271d14..5afc68368 100644 --- a/cosmwasm/enclaves/shared/crypto/src/lib.rs +++ b/cosmwasm/enclaves/shared/crypto/src/lib.rs @@ -19,7 +19,7 @@ pub mod traits; // mod aes_gcm; mod aes_siv; -mod ed25519; +pub mod ed25519; mod hmac; pub mod secp256k1; diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index 96dfbc4c6..9f1c3fe6f 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -912,10 +912,10 @@ func (k *Keeper) handleContractResponse( logs []v010wasmTypes.LogAttribute, evts v1wasmTypes.Events, data []byte, - // original TX in order to extract the first 64bytes of signing info +// original TX in order to extract the first 64bytes of signing info ogTx []byte, - // sigInfo of the initial message that triggered the original contract call - // This is used mainly in replies in order to decrypt their data. +// sigInfo of the initial message that triggered the original contract call +// This is used mainly in replies in order to decrypt their data. ogSigInfo wasmTypes.VerificationInfo, ogCosmosMessageVersion wasmTypes.CosmosMsgVersion, ) ([]byte, error) { @@ -1198,6 +1198,10 @@ func (k Keeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller return nil, err } + if contractInfo.Admin.String() != caller.String() { + return nil, sdkerrors.Wrap(types.ErrMigrationFailed, "requires migrate from admin") + } + random := k.GetRandomSeed(ctx, ctx.BlockHeight()) env := types.NewEnv(ctx, caller, sdk.Coins{}, contractAddress, &contractKey, random) @@ -1218,9 +1222,6 @@ func (k Keeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller response, newContractKey, proof, gasUsed, err := k.wasmer.Migrate(newCodeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, gasMeter(ctx), gas, verificationInfo, admin, adminProof) consumeGas(ctx, gasUsed) - println("Got admin proof: *******************************", hex.EncodeToString(proof)) - println("Got new key: *******************************", hex.EncodeToString(newContractKey)) - // update contract key with new one k.SetContractKey(ctx, contractAddress, &types.ContractKey{ Key: newContractKey, diff --git a/x/compute/internal/keeper/secret_contracts_migrate_test.go b/x/compute/internal/keeper/secret_contracts_migrate_test.go index 53260e4fe..c643577b5 100644 --- a/x/compute/internal/keeper/secret_contracts_migrate_test.go +++ b/x/compute/internal/keeper/secret_contracts_migrate_test.go @@ -26,3 +26,37 @@ func TestMigrateContract(t *testing.T) { require.Empty(t, execErr) require.Empty(t, data) } + +func TestMigrateWithStorage(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[migrateContractV1], sdk.NewCoins()) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[migrateContractV2], walletA) + + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"Nop":{}}`, true, true, defaultGasForTests) + + _, _, data, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"test":{}}`, true, true, defaultGasForTests, 0) + require.Empty(t, execErr) + require.Empty(t, data) + + _, err := MigrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"migrate":{}}`, true, true, math.MaxUint64) + require.Empty(t, err) + + _, _, data, _, _, execErr = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"new_function_with_storage":{}}`, true, true, defaultGasForTests, 0) + require.Empty(t, execErr) + require.Empty(t, data) +} + +func TestMigrateContractFromDifferentAccount(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, WalletB, privKeyB := setupTest(t, TestContractPaths[migrateContractV1], sdk.NewCoins()) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[migrateContractV2], walletA) + + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"Nop":{}}`, true, true, defaultGasForTests) + + _, _, data, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"test":{}}`, true, true, defaultGasForTests, 0) + require.Empty(t, execErr) + require.Empty(t, data) + + _, err := MigrateHelper(t, keeper, ctx, newCodeId, contractAddress, WalletB, privKeyB, `{"migrate":{}}`, false, true, math.MaxUint64) + require.NotNil(t, err) +} diff --git a/x/compute/internal/keeper/secret_contracts_utils_test.go b/x/compute/internal/keeper/secret_contracts_utils_test.go index 2d98aa7f0..dd9f6db5d 100644 --- a/x/compute/internal/keeper/secret_contracts_utils_test.go +++ b/x/compute/internal/keeper/secret_contracts_utils_test.go @@ -277,7 +277,7 @@ func getDecryptedData(t *testing.T, data []byte, nonce []byte) []byte { return dataPlaintext } -var contractErrorRegex = regexp.MustCompile(`.*encrypted: (.+): (?:instantiate|execute|query|reply to) contract failed`) +var contractErrorRegex = regexp.MustCompile(`.*encrypted: (.+): (?:instantiate|execute|migrate|query|reply to) contract failed`) func extractInnerError(t *testing.T, err error, nonce []byte, isEncrypted bool, isV1Contract bool) cosmwasm.StdError { match := contractErrorRegex.FindAllStringSubmatch(err.Error(), -1) diff --git a/x/compute/internal/keeper/testdata/migrate_contract_v1.wasm b/x/compute/internal/keeper/testdata/migrate_contract_v1.wasm index 38b774add2736cc0a61c6bf83ce5894684f56143..a49c4ebd98238e63dda7a1080c266a557f3de554 100755 GIT binary patch delta 23959 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 delta 23975 zcmeIacYIXE_cy-h?k3sIZjzfqfYjZEKqw)hcgY3mQba^ldX>--5fvo~MZiKCWKfZ! zqJn}!(0~dAg^#EpMMO{(#EOEz#|DDC+c>p5u2qhmV`$9yVm)-IGR59`11Ps|T-> zhL0UTWw^t&@O)y9f{7nIY}llMLkEu=KW@~}!DB|WOV(3 zca9o4&JoFlKD%vsk!R=~!-tL@ICAivjwl9+!PCIuQwC2MKWQ-NSEPC;-ZgyEJp+f{ zF?iHCl$_SS*IfAHCXdJAa68E1neKKtJRVPUw8!Dm+;}2Q!#~aA)f^0}dE5?<&*9TN zng&44;fO{9hsWu1M|*s3w8 zr_-5;|1Kx$fEq>o%6~McC&5bq00xkNjvf8+-=@#S?1Kx9@#r3BQi8{$(1ELHiguER zoRzfX%1S~WO<{`AiC8w^$)i;XF-cX4|A>jsF1cy$!DGgZAIeJU6FqEr=;fBgQR5~L zpEP3d(BW(nca9oAZeTOV?c#f9_31BbwYO7z-&=3%*MGpkL4$`39X5Q#$U72p^XmVo zCEnejVWUnRO0#B$zcs?ItB)?WzSO|;qYWaRG#^I0jM;N5rz!M|8E3g#tNn|ZNxuR;| zS|_S8u7jiOy7!{)u%NoRxr-_8mbkv+?t<$ds-%Xe4W37MZoqY;r(>wRdUOXokB)AE z>vPeJdvA2jNJWxY))_+CKJ(f8ri--cVqtz|`Enjbh%VmxfSu;$-d1~SayxbXMP1W< zT=K1tDIV`*tmboB*mHbLjVOgX&MVIPk`o;5!Mwvy%sfj3#Scyxg{J2xbj7vx#HP5e zh)wso7|`W+C@C$U$P}Evy7=70?DR8?#qTucP=TLx`)w)SH2uuRg1C{Cu(ZeoX;uKZ zGDm^FO02(gWz|hH%L*O(N5y94N+;LurULy3u`IqbEfn9x=O;dHH7(TawhKk`gzB_h z3`oeQRboX#Al8P-F7Q{!a4nHYK#Baeq{1w+AoeJXEyzm<*bKYf$5M|V4N;QPfavd!5+Mp zl)vu8>(Y&X+|!UYj;b<_u9EjTB~j1-Ta=w7U4cid4_^>L8=u^y*i0!}e@)Q!sr5ofZeC-)^;WMJnYBNtjU$h;mkcW2fK z)sz6A3#PXrb4ajMnM{QK6N@B9GaLc(IlUnDO;zF5e-e%TZL%%hP%P%Bs04Ookzn0v z0F~jIWY}2NiDmxQo_ADJx4urC^f#Vv>Z2;-w86~Ibgw_MeN3c<#jaa#j%k!`)(UDl z9Zj7pF(Foxh~u)hf!-3ptil8(HnV;yKEcV=9D5UgH6S!1U_btYr@b z*`j(XjH6HWIvyK(otRg>VV3=7iY3zPk7ysGS!~&L>qYad+BrUO9fnZ}!o}K%Vw3j~aunMDm)5N@6pm*>4W6n_)Tn~%#TsdViEW-N zw$;xOx7KU}t{<;C3Q*rS%@9knlPiUWMJ)Fk;g40Ozau-@n&=X}CMmeGaX#_S4bkn9 z>~-jNcC8xdZe6VgA@Lt^u(3+FdSCx;;ba*Na{`*C`FOCYFCcQ}&UVim<7f(^8eTj<(Tl9s1A0lh>Y}7CrKAg^t(cwT6(s&C3n(#3Gr4u1t#Z1RB^l!)VisW;n}Ao4!1Dwk$>ljE34 z0d~U70p{L93bOR$TYebQ$T`K^D)Cdxwji)ct9qfD5~ZsZ;?7p%+I(XVG}b|Cz-N2F zSmU&7|` z5v2dHw0@0?EFpFw3#|Fa^ZGdjy3jvp6t>L*VL{-)Lz$h8pwI0>sXXb>y#?4zahbPAu1k?XIZ%Y@k$osZfHa$ z;+Y$Ggiha=ZP}4#xY;eO5Zekn)NpnLJQ;zQ1xzbNK(3uIm! z#u1elC(Cqh}T1j^9}o>bbG!4M4ZNXE{)w3A7hL&xo>} zRYmQcsT)&nY)F}pvyD2;N#IpBtROrv*p2|(ntnly>6Mmz)jA2{&8u6_TId>d#U&A@|KQ|5(pi#g+?f{rk2oRbEYeFu*O^-JV?OCsh|^ zIE*VM6a-fy#@*f^wpa-(8sUGZ0)4eue|uW2<#15cyFhJue2RC5xVb}=C z_}xNCK$y|5L0D@bd`=AL7o^pqsNciol*XJ=O(IRziTiJ@sp{%_-&3?i7!D}z`Tm3G zS>YbQ0kh5F*JfAX@PPq!LmXySdRVn%?q0K=To!j*)q4zBxxwbnis(_)my0rnrbgj; zSb_e$cywS|lqDZw46P*oH88>ATn#3rLBsBh455&FF=dp9D+6z$RU3N^nnR%L)4?rs zmh;%~$7E~n0G1iJLxTlD-Ed?(mUFu%P^oS>q0(%}D$#BTR4T>}$)mMm`H&iUw z3YC_v%|WuKLkus2m=w+6c~i0RywaORy2;IR;4Ce6gCa2kMH86WPDA}srYa-Fj(%wy z9~v43df5bD7}f-YA0Kv$ZNaHNcUO2gCxRl69ml|3TKG+fzZt?GVX zTe=aAEF;lhQdR@!U|WAYtUq}~{cBkL%Ogyy7yCx!v2nMZK2MD=R_fE{NYmFTbZR|q zs=@{#<0%CaVS%UxZbcBySYqO{K+1_SY%ES=VHg&%V`M%IP`jfwJYfDEnRp&_M*(E? zQtuk#{2jbVy0=eWvj|g2E+bMmHIAUq9dKdJVvV~Bg0SXn$4o}d8jmns5L&Kdj#x3O zu5v21#4n?&z_G*@OaaPS1v%b*rp_=zUlv;n8h8(>cb7i`3jDpGnj$1gG#K3oPa{V+ z0eQXD z3#x1(&tM!AR3B@glM!QifChReZG3v{a)Jvt#@DE9`hF*TKLU__#o*8Q!U6yP!1!Q= z^pa+L2P;(u0B^8mJf~7=!hqUKO-~=nD`}ihteA5%A$}Hh;{yMul9N#j*`~0jIvw94 zH5Aojy=A61Rc){m>Wu_m$N%4xs$3wRzvus@D*p#ll_flckg6O}h*;p-LFb^T1%(Xs zqR1+06nY+1WJZtsXoa}3IE$9b`a`KMJuU|frE&DC+&h%2P^qXp;~)V3oWTG+?xVU9 zDv*<_?xhDSlw-YJe^zyn&}Y`|q4g6M7#v1!pH+kkWA-RqUz~kcs2ceXuCDi>fr<$a z)(TZ%LB>Jp^AGa&%BtP9F@$30+zFukcW)EN=Jdc*-MQ_!(OeF+Cd^F|Wpg7FjJEJCA6l#E$reQqCz>=>4SEenEyqtb zRbE9^j^om7@z%o#@JzCTv_@2WvL)2Z!Y`0%{7hvC5nBy%|Ue~22ik}uXh~25)IfaXG zd$nk|h*!H)7jfuo5|Air3g&6Yf+W#HL?);}kEbQX%1X|A#Yn+{$U>2y8y3VP3W(rf zLw}dWiHtx5J8Rx~%hr1GrLX?tqQwE|IJmeC3t%x%nkyGK4(*6U@T^nOyNh#+-v(v2 z{_}hqPo0qXV#A%<)%+g=^;OLcQ@ z!%m2r+fFZ;j_$|Edda5Ww^w&OAs7^J3OZO-yesoVD<0ly3(b1G682-wgBdS->2g{s z-dWn1z7>Bg9Z!qJ*vFeEJ;k$^X=$!WxMvq&AiVxK@4nrztg-lEM;sj&*-!MMuf%;% z+}b)!+FHI^FyXQvB7d9lU~L+jC|#Uex=NJsPY$DR#FQud(I#|WM_hR_{y!5ik!Ff* z%kr=4mJJ7_LbreI*2(jD#cpLrWt#ZE2Tdcn4b9Cm48F-wqNB8QiF6l&EGFq(9C`Dey-bGaqGKFK&Ei!z!)TIunc9AKYYC zT-Eins&t)LxT#W08#)d-u&-44daJz;h|Q9#Nk3$@|6ozw6RVO!}%(1BoNq#;5g{!uaBX(#k$vJx3yv7oT*^!5-$Yw ztSYeu1pjE1nS5U*@&$@2i2RL8mF=F(lu84}%ms=bvGtAnY2C(_Z)T7!NWX?IR$77_ zvvoeK`tsHm3HC7qq_#{~^}6V^Z7J;(Uu+vh8${df4QaEOvOTZXW}Xu`JB1aa6W+8? z!_a1zUCM)2`3v>>h1j>fex+Ru?eK=okG=g;QK_sA?Uep@lo9paLrmzK;@+~flq)81 zWejJwhc-`2K&B0^Adp0>r7LUv_1H#B0Wfo#;K`p3NII|9_*zmcZ0yPE%mY ze|L&@q*&hgBn8DM@7_c^Fbhi+$F zTwCoa#4(Jmdvak-XZBRZbJX6$Ny?_Qe8e7@03*zKSDfD)gjFSdzzM`_B!TC@pN{Y# zMjYRl8F+{7!N+qJhab9n^%L)%xXc4OB4Qs0tN(!J!-{CsYeh7f`=3fuTP~cfCgbcH z*rcIjV`BgQ`pwO~7!Bs=Y~di>94#D}!~nNn!Nu8GYEA978MD`N>qN9}aUdI#7UR0E~&9H?$Z@k)$NSnkCG14FTpGZYJfOYE`pz;YrMy8GZOh=po@xGu(a<53JL zzWQ(~l-2)Gbp*e~hic+^?V)bXZC`MLCvYQR6fVZy_DvZ4iabj`*Ct5 zt8e%n8x`U?(fngZHSpuQK=ts))o?BOI5);b7HPFU{c#4!@gB))ZjqzPEAV2H*%?uY zmT&UQmJ@U$Of-2Nb)+^7eDRTd^zhM<7P#t1rzM)vD|S31a9D)dhsIVM<)N_eXeO>_ zkM^af#JOX=ViiT@3?XM;}yT4pDN`~dkwzA~L%%1rq%WJW4CPLH1$|H?HNUu+; zTk67|vdg4i%>MK`^uO!VYG%)T;HWyQRs8ztN>s>We^1zT;e?g3Fye){^@_98}Kl_{|_{Zlap-H0P_;tN4DQXJbdQo#$ zb*PKuOH*5xP(S$_+96?^Dkr3R`FOdV{-p-=_B+9L+U+Ygu8Hcp=fpx7)POJ8^k#n1 zr;}-J&T^{!p0H=P;V-x*ec^I8tt@!54m#<6((EcjEI2t5GPrQE7Pv?VuF7u?atRwsOt;MA?t& zR<7A)>~`_l9)>Y<%}#xvNIRF}^`MmNI2V$Bb}DA%C1-ntFq}SH)jAzyLz%7Jsx=>~ zHO@_lIKWC0%g$$u&(B2z!>Mzv>M46LTsTmYja~TmF*W=?Yz|r0WOz|t(~GWgTF~zX z**BfH4-AGJl2V$ic*Zz4~kEI z;%puLd^hBF&(C&9=`ye}9*5oYEkE(@W8u!1BPoTfh>v@QCD!^JOuv5%NQlsFC@ zudk3hyi`wg{YP?kJZ1%I8Zq|JsaBiSxfUH{%sw7N5@C zuYmZB)^)#Cp+n-9-x?#HedM=v`d+;F8y{c$=C_t~Km;!gQ6;s-%NM5O6i4pG>u9SO zcX0^lI&d)y%k|$bc0x)1@5!lKmAsX3K_;IEvU@otCjO4oc5<*zh{WYnI@K5Hm!g0p z>r##6@|pA)Ck{DK;t7B7rCK4U<}$9TN)#I}CC5|G8*2p=z~E0b+Mp=~-8=FjwSLO#^co-(jZ~1V46#2GeVD5D}8H zay3z29W(8S!4C-7lvjC-ARZ}WG5%pR<@8V=Q=3}c3yH~TVR#ksyUH2eTI zsxf+T6bbY}YGxHPg~MZZH_AGaWp@{4rM+j4uxxFC3!B_Hm&6vq2ilm@`7RoSzRtO* zT*Z835nRj05oGE(S>78#_l3AzfO^PHx*`dhmVG1XTB`0Qk4I9of6{j|&mJ{+T>4-2 zj={qE?s2uQLDUkDl1;WJq-dPvx|X7G99v~&6~U7|G|<#^a~Ts&UJze3n(TvZFbHJM znep4Au}iZ`J_yeoVw#WV!i&hJUb+!=bG>v;KXM2CBy0Pq3A!2VBhy!;%Tga@<|set zt5m^Zus7yYWj-9XGj)e#h>M59Ex%>UIx(Q*d)YUJTH8KE9*iN&iO7Mm6!Ic6BaViG zuHrZt75kCq@^~D@!J5v-A=Sz*D@)eXDHz8srGwGz#w6Q&^LM=&w#i{zRl>O-$B zsYG+GQT>B_vJ&-;eUpbpXdNZ-MPC){zqLxH0Mbg34P_vlVJUcdDH%g`C#Ts< z{|TUx#G%K>JV#mA0f#R}o=Brg@~0{=lB2SARg9sd@&VjJ5YZ;Y*{TYnMhe{ph-E1X z@EmR-z(}bN0;<8O3UFzv0*pQy=axlLEl9C<;8R=kN&h!T*$2(W)Q+Zd20q`z!s)vP#3_r$fiK3Lv=dD zUU74i%NeS}j7-RWzigbT-fqc+>W<3wnUqN-@`FrjoqWWS91xIkVPzSnf@J-O4EQOD zj>wGKXnsrvs!@{cT$>W3w=j4Lb_(8+5BP!Qce&h;nR37U#IJg|?595UO(`fDcT_eD(tWsX3ep&}*P4~h4t;zO2?TC>o(YWB6-fbE zSdAiW2tKS0h=mG5w;{HLLBNYK#Dn2DlH}QHlxXAN1Mh(NUCoFwCJqyVwn(EoRRUGF zRL20{BJqh%mfg&4HY-!jEaEC6#gZpoe%36PZvB*8)w zzc~y905FL9E5N{?HK-xXpt~!+9KgyvHHlFx2=u)QA;mvYjNloZ1#-SgT&)18e=|x zYCijU@8Bzb#!`u&&xAdn=4bDJhodB{-4Dfu(IJFi%d#ia@oo<$Tc)l zul8&c>roqw^bPf>I>zGRdT_p5Btr76aQCOIy-hCS%VV-2SNViRxfBHCtGU;JypT(^ z02$1q>S0()d*)F`4JNv@0aY`1BDKegEj-C<5@*tz(mFY_EwyfH?Yv=k z3;7+zn!SDLMxb{>m4w5XCF|vdwoubj-qxy~@g`eL6V2^+80k%TR2dt#KuEl#b6`7t zNIN}6)9)O#_I|iL1K1ojQZevZ7Yr5kj{l(025+{dz zkO<__s|VEw^voU*|6+Nv2eqIVWqMDAJijO1hPo$v;vCo#8GR$=p|0hP@Q_R7s2dTi zEs-m4q}8-hp07>0F_+)qLBcMM^l(pF_n)2U{7HRj$*pi<)2;0ze9%J1g6-Vd z8WYCv@jH!`6-uH|Qu3FQ!m{vIjHj#u4CC2fp(F}0C(M!rt26%G>zr96yWI{yh{*JI znwefSvtc=KUP3E`9g1u3HthdamTE5pGdc>gW zPg8LlF#sxiT|PAcfyHroU;z9;ne+^V3p*;?4a5rjsC;%HQUXWisey1DM`f=;7+pu@ zYlG0>P5J#GN^7vwoDQp+6H?IJz2?ajTi48vHz|CEiC4g42le>i;<9CJv!|2&wlFC9CN}=pk*-Kl*x^I*e*&7c-Fo4ao^7CNNCK`dQ}4 zNV1;_44ofk!7xh6H0!jT`W@Y{21b&nKmk27j3#FMn-NS#dLG^e|6R^} zEg!CL7Wbt8EE^1`qAKT9Cy>_W3uT3li9sB=aRTPNe1A9vqHNHghGT-9DXWg4+@7i| zh{2@)$!)O-;L<}XdOgC8y;WX|m@H@JuDjwU8q#KR%-0luTn{4d-y{yo|t~KbgSyUZsqXSM5 z=F(>>%zUEA87_uHBPr0+s*7=O9>i>ZEfy=X7lDkpk_KdO6{E8K9kkJ-m|~tJjiM?s zO4fjMPM!z>*BC|p(@oiggb8ipEX`!UHaZxk{~=e7q7_sm^9$&<=yCzcXA7u9Gi5J9 z$7l%1GL?eA*b4Ixdnhmp3tgr;=?}}`Xt>Fq@Z(Z&}{++ zqVegQ$1+uiuB6sBh^X0=N5EI!PavioLjYeWA^31wy~Ww^{>hqJ>z|^nKhR%T>NKktR`5Y33yQ&DqhEq$|WmnEC_mFiGN@lQ6Y}L;;3_(JbKp zQ$lLFHnPYtWQYtw30jp+q2AYEvc=tS83@yy=0}9i&ml2PXz%|@+*|<9zdjaMIL_ur%~t2%MVZ;`atGS zqh9(i49?j~kOfw+$fu_v!u~^^pGLRS&$8S7h-N>KMj=G^hr}_tT-qmpxS#IoHiN0d zkjG!kMlH7fw-VT+5}4BdO69}T6+xh~wM;9-uUlPB>f%D`P+cj-q|vt9a<$mA^_4=f zcve;|B7Zegiy@;8P&qg>s@#R_S492bUbg_grR6t`O*}QjA^3Q9GiZvwfTg3v$^niO zQ>k%`9d3Y}`7CNU-lSsWTppFJi>d41n%0V9s%`nOa?^5!5rsozHfMoIg%}2Tu^7wT zL$cZo_=kP+_8Exd56NjW=))l)vRu0D@+19`mWztAG5Mq5oT5yv2Hd7c4tnfbY|)ha zP|W|KavWR5qF}>JYUEbY1{V6V{{57k>eccs3E|YfKA%OSLJRB|%Zynxv8Rfa{M1!N z6tJhgY?J~1v6wLQUC0|N42ISIR-dDTBk@q;&$F>NJIZnJsxvYBuf^&Fr@yw?D+^K)ly*i7A4Z+63a)Jnu(1|&8Q$s z|4lyf2#uX?QNk!}gXHh(%UifZZQbRzsQOci_LDm7Y>gy*%89lxV$4IP=^ImxX)IR; zPAv#x1?7i^%<~!;SkoYLpZ8vZ_5Uuzev(^S8TRkPp1+hcSI{DCEcRGUH^`wY(UC_^*{8=Pui{;*D5mOY&U!SGECYEB{4z9)_ zjhDDfZ#>MPF-It{g;P?0j=IuUvfp!5nhxWIoy71la?W{TZpAVlxeC0*7t6fo>2A>Q z!t)f#oxc16-HdJ`)*uVJNw!-9^E&Oa7>nRl`rJ=}4c|Q4h5R)l66R(zQ-WAyXKQ)JB@>cg z8Zpu$d1wRG)7~hSUo4_Tc^fu~GGVzp7`wykg5Ws)MW*zj0+;@h?D-0fhyKc5L2B;R z1C%a*d4;<0@ZLyIqx{Q_)E-KywFy6-N^9koSLxm4f0_8;3VB9>9?ia&z6OQ;tMtd$ z=rt!=u6~`KOtf-;>=)n!ajsMUm%Ql>dbFus;q*ruN4{e5SpqfA9cA|G0Mt%@GRZs! zxp9>@p|&D9@lC3R+hcFiqH^I9pZPY0+hQwLA4PJ+R(hO@muyp-$k;~9QMPp(thh*? z-bQm9fssNOB+!S86ECJXRc*k<;Sityw{Wl7j(wPS<>Bq{mqn$~WzadcSXS-8PsCys zQ}{OBfQ7=|w<#63Q*TpR#?LG-m`NE9zYu;#?cf({KRNUKyAS^A;NMe|)pk-zss&Ta ziB#7#z%ukZX_paVMC)C=+&3({eZnqvjo_JPKd-N4blLrr&R*8=vW&MLVh)^WQ9#o24 zb`U!y#q#(;`WiXcT^~XnMY7)^{A_Qrto9LY$L-6HXe9khc0EiTb!#Z{FI5EnQ5c6$ zAEp}dmPyBQ&In5no(-;0Td3>J&@fyFo5LhVixbBvqE~V{nLTrSD6)*nM&ePQ$^2Ej@-^l(q6r zv#|MRw2FQ%{q!?Rpd`~WurS1ai2WOUl8)2)XoVYRVO(B$_EYL4x1GSmv`>yZLHE?& z$Ni!XsWqfoLoSd@kzNZgDuq`ZO=x%jNzB?I!s>lVkCapN`Ip#FRCOsZhtXJ59sP=q zRxCOAHRV;cv{!!QW0MlVUQL!Qhw5^_!PtR%zCmPAB#Xa+#q5@wzX1V7vii3WMUm|A zE!A~@r&>LUv_&pl_WW-th?-ZvMIvU4{Ont*ft%|)oM{Vrf~nu3@VC+x-_cuI!(UWu zD3d*hrvIv5z0XZ0%m#&J4)3z5-N#RGI2^jeiRnfUpyGp;16Y1veD85FtPUvb!%67Bwm=&}bo` z1Vu$;3BtYLN>r{!MMWTGpt z>CU~M`M&(#m#>viznW>9#{S0gM!CcIr;YN^Pgt8DC}FPoLuw3O|IBDf$#!M?4T|Q~@q{`9d6Dx15(A5Q*qTb<20{Cn_e+` zO6P8+6FQYmuN*f?^ARxM)Qy4?M~|-epL$Kj zv>VDsk1wyB1jr%&E%)M|=1NN9T;t5e!)~6Wah{Zv#F7|KaxxZdELo>Y>8VKpx7*|Py740+pgl?Rcsc%gGu*oF4tS|YPP9rW3Jmj1atN$GwU5YPfh2%vxZ=g{Y+;bRnTYDZ7uOB=3*XK zlFO6j&Tb+(l;oBzCFm}fo9bXtN$#A;C|$WO`senrDQw0JkBez(-dtChnbp!+OBgs(I6dt1HJz;T8JICr+F^n&db#X-q{VbE&n*l@-1+sjO^F`Hb?i zib-Q!%wJYEzM_0e*;VD!D_lJBCB`(9`KLe4OI~JamtB5E*{JfXMvti&J8pbs)r9oU zUAlhHGj8lw+I{Gd4SdEm*P7Q|f5Wt!hWEXT-OJ{&1#CXMhuzKYV|TK-?6hz-yN%6e zbJ)#~^4r-RtcE?nR*hvA+r&1rjjW!1!MC!1u$S2D><#uR+sC%CkJ+2-BlZ?M!2Zp? zVqddw*>~&^Tf|rLC-{?m1%He`&R6kz{ty0l{xAL%-^_pD4g8;c2mg`3&p+TF@*_Oy z`EL`xwRXB^vS+MIJw^DQEx%WLh9P~LFVD*Mw$6U0y1H5ma6j*F@MO*K8XlABPKBGj z=h~>BdyA1uO=yMh(u8jKo|xd2y`L~%VhzCeOkZz&zu-Fy-@ZiZv{Pa~d{0e08{aP` z4vv9mSOb!}Ab)LAFMO|0qPBM?wPw#O@RuOj-hTFO6g)S>NOfvZtJ(S^*8B`&{ks_pxpx6p}8sG75b*Zk=_Gahl5b^g7Ejx`h?bbE)F&xE6IkG0=-4qSHv(dS#)2 zZst|RF0H$(7IR=+x00R|zma6}LCGGwzC%>w`qtoJe}|y;)_uXwFp2t>*$I1X7VHW3 zi41@tVYbJaBq*UA<*b8>qdh4qeZLAksB(!oGlYDTK zlTRfbQhao}BJ^GuYs;2>*;7_^Nse_>%QNKI3y}Y`-xPK`8mv9+u?7bVXWFN%~jpoBwMquLBa z$>VK`BPFEW9Kzb&rcCkQ3y}4%~V^(E{zL^dP^H0tIZ9vihO+RWq+hHJkY(dA7(1J@l_63&~b?m4{;fCUF z?^uJ5l*&v%XPKp_{ zpi9Tdcx!DN9NL9!a9o!uk&<~RVc^aeUC3#*?HX@`3}UV5IzUker)90{+Ekg9?ZHfK za4>+ulk!U6Og@F8qC;Kti=|XOx^x}^IHm%V4T?zBJYro2|~^-vF2vY?@=OoJ`L!dd(wP(YtL*4UCu|zG(fMBEXTIGXJ2-k^;ORi(Fp?t z!X6R2tgtTV)xU!y86sT47prlVXmePQyfe{@nW~zFi2E=1`lms%m~>$ZFfUBeU-=^`-HrG1Cw1C1jvdYuD4$5Tk5p@vvs_0wv(ZfHbtZW zvIfKy6*3EPN634n1Xoy-Pm6a)4DP7zw6@^LuG1z)I703y9h|$k-yoDc+^=&a)`PjH zqss1nWF|lNTO28ncDce@)}J(efBzT<2JVsrD=;U8C>k(r<<1W#INS}Ghh+)5w$&!h zHVtN1pA8}&DSW57HZ+fuUMZ)6QjcH2C2%GO)!2jrE|L>$w;^nr``mt zpfaSl4eHDuwvG=P3%-?{*~GeKaE?+r3_R$GYKAhEWmer_ihvFcrUseXZ5+uDm}-cEuov?=nDU?OkVC`_D1>3N-@^Pff9k&n<_C zyZhW;@w7Z<o$|Rh2Uzz z0S`F9^1&B~ z?EGT>l*62Wb>;=lNyHa)N|8|=*VoQObG*M5yodsxGcRiIGaG6^iRrV}UD?Dcys$68 zS6q0ztkp4bwXEiXu$o@fMpo#@oOHjdv#r-JDhG7kh%BrBh*nUkaU%xfd))|=t+x)3 zxEp1+T--iMcHlML`qS3mE*=43;F8Pny?$(#b?YTmjZ)8EQY2F?lfkwc7^cez=xdyz zBw1ZY(p*lMDPx_~t(W9mFO2lddYRUzBNNhz-rgEKy@{Y-E76YKVf{2xH5{_cOUZc# zuPC&3U!IcqoE)1QV|(<{mJ;6F3Sa57j$GO#Qx+wdn)!x8GP%CND!i;qvdku7ZE$9l zzS1hYtZA}xeSln8rLVH?yv%5|l6V||ld#8OZn2wV=Bsvd49&fR<|38R+$t;e@=$_Z z*_t`3z`F4AstCQQ0a?|nBxtoC*;*ErDCT-h4a~jdic#zd>zOMkxOPUlUiFAkcDS-# zWRym9gtMe{5+EHKVds=PWj+}LI@=kdY$6emO9=ALRrv`>kEzn1wEC4bRV;A>GKI!a zS>`Z6+Ljcgxl^`~U@~)$O!+afY_QgqUBFgsaE+>Aplfb<@Ak_{*Nx;N?h9i5g2?-UX*fK-` zXkG>SZJIrRfaaCfFIO2h-@U~54Shx@5J{wKBgd2?HE+ztb{-lR@C}87b0Gvu)Jb(S zb3-YnR;>L>jO#9S&nI>^#)7bwXb!l>|P)QT8-_jrCeZC%d0` z9UnE;(ediB9i_IP9=64%ncvEkSFe*TswFg;kNJU(!pwiml*dL<%iTB>ZhoeaZImco zkyc#hr?IVA)5rCLvTYdG7q0K{xI(1U#*?~UabYX#k@2)NQf?u?r$_P2ZF+SjVT60W zpc|7IN!VQ#g7y|^+o^Suu*Ylm*Rn0 zK5b2^>Y|LmZFnHer>dGuS~9JFRdq!wXF@3`95$iYrs&=YMG@LEtUVKQ(8JLQgYeyN zVmG$Vx@Kbgg4d)XI+Ec<{Q3|aHwCG%qb(D&_%qeklyRBXR}}`e}w4 z>ibEpnkbj=g3E^#?zj!(GWTh4`yD1XkKIh-<^fDdvKN?A)#Smb{`BN4dn{2NJ+eo{ zX(EW2P2$1(8y>=NCu>+e zB+#ad2lF?95= z5uaHV)Li{htPvZTD!W-C%2ksW0TD%&ty4NBB%qoP=|)?~YA1_ip+{%^dMU#Kb0z)i zb+aU0ATz;SBq941WJPmVMws2|4cn?P&pjdJQlSF~rZtlm*^RD8F1k0p9XaexW5AiT z#e+>TvdTIZLLgnlH(O=Zg$vr`hF!(3&0IM!mw5<_9mIPQ8^ngV+()D8d!3TK_U0OZ z2I|)H?yf^H2B7TZRUu7Q*h|)d4$Yh@Qco>Ndu`aqr6es3u{A--1SG=;RoaL2A(c!- z@`y?%A$e3KDKI{!k^v;`;ncHGG7YDJ>4HQnhsJ3Q?vln5BucPlOxMj)Lep{O8MEF@Ow4=d)EXw_UY-%J6f!;#1aMx$DxO#R_7Rpew} z=v7sQ5K6R}JeXzolNnu0S98#mHAoH)8`xl2Fq?!lhXBg!*u=;p9w=4H7?_-FG?Dq=w86;%RC2aIXi1-` zN47r3pdzGCno`6^g>s^eUxLO5B65=ZBG`Ti<`PL^(1dgzbvhD#Hz5+5ki${`f%7DZ ze6t<+Z{(Z5Lm*s{lFZCRa5;lSCTW9jGIa?taw7C?2PrXB43|_uvrDw|f~XoM*-{S$ zO2Vj*J*?j`$aFKqkv1l&*f#phHefs@nkjh_8l0RO(Z5%ivFXHofFj0w)`pDFmQ6ElQN;S|W$(+oa z90|09l9B+@5>=a)i%RZcscmN}u0VyP^oPh%5v#qXKbR5GEUET6N*x>bnrq}i&$=V* z$t4$>7csd2_L9_ISdRXnG82kAFsQ-MhOi5(K8LyJ2plTWdMYw{NU8z>%^zJPVnm3c zw#uC=`wUJ^6zIctKFS9Z9|!=)!yLyV0U$2o*5Ut@3;*w34UPK*XG5JSXS3Nw{63kd ziFY(<_K?EzT=A4+>Y&{Q-&~^I!A*U}w8jQ)3s>?C!p#VPp-?4vjH$X}OciVT7)$Lc zEj3&uEwy8;r4~uP(=iHmFe8>4W2nXdBSTF(!BDZK9*$b75zzx0u_1}Tv{<4A$xu&e zr-{-|v6T7SbFu^)@!s@PBEif89)d&OGs_W*R<~oyzK%N^SRSGG!Av za!{D_OSIgGm2$Gu02Y>NV)`o<8YW$(K>1WAN@@U;vH9v)C>$@5;FHw2$Ua_)lS#-4hsG!W;)fMd?S=O7z%_Kk1|XW#YC$v6dEzN!#SdMb{K zm_3zbR)sPRuR24gJVG;sV#Q(CUPKl|6akH@5KUhy*o#zOfzSe>0wL8RnWB@DaB0}{ATphRw6tyAkKO8n^4O465MX(D2Y+Y@dimBvbB)nY&jv+wqG=#7{&8yi^TA6Y? zV1}yYo`&;-B3V_6fP7L5T3j0OumXbR#KSTPrpLnq1oJsC%s*fmd^08mn!awfPYI!E zGL9v=LKwTqL}ZW-K*;!p z2ho=hNOiiI(;|nwJ2@{YIki3xDMzksIRwRtQ54(BlRCiv80FaVz$ymNg{ZxGT90%5vyBrbB7Fx+uH4`dru9s>)~Bq zQvvdFx3&J(Ty?&bZLPX9KmJtd5o_&^A*C~_Qc|?Un12j`6*CXemW&xtmp29`Ck7Cm zF!P9n=Hj?C@BL<~s=5%XzM1DFRXqXhj>cBK?EUK#=g}mN9nZDauJ=3G2h~{jXxJ__ z=wK~c-s*#5E2lb?sxBa^ZA@(WSVO9XegBZtdVH!9}Oqv8&b+&WiFqVdgEH;NO9Cn*C3^=#Vc{=_^A*Xo6 z9ujU%-Zsd&QOKnZ#I1#_^|xKeezuBlFHDZPMX2w#KE0y}Xu10KoIJJdN2*U&@0MTC z8Z!N5x0eHn-9gs_bMCmIF&Xn< z30J4I!QjcU5P3$h!gs0T*>~6@)|9(jvL#~pMAnWi6}L=elh|glyq4v#XNB39b+fAH zJ_M|0_Yl^kIfP|Rz31-6pyBtnfSj+n_p->f1z0|v)9$`^CJIK~SBdX8?z<*Z3{9ir zbLNqz-8Zi|QUFz_Q{PwT(KX}xciTXTO6E@o((?IF;=Am@)2YIO-hl6UFej^6TR}$= zbdtkpvcplt>Kg0l0y>JgZ$Xw-_&}O9ig=wTR%7kEpN^LlQ6aY48t}krIFFe5Ku?@_Jomt1G_*$0;0_BK++mSv?OEbs z$E?ANhzW;9mR0v~hP8N6Iu3Q$ELsmthZ!9MoK9_Uq=G>aU-BbIt1No78dw}^><*y%*EpHtW#CxnNDwvLGmLw~P+FCN84`uT{%R9slB?!|M3G7VFn#^FYVl zwe7PVUy2D6I!FsWtWjN-@ky?AptgVHq5v6pz+q?WY*GLrL@RB4ZlTIQ16c(p&RKF9_wZ$y_w2Cn`I6C;JiQ`-Rv#pItDb$ zTKU1beXFCxgma^_27F=nPk)u#gqw@FCXd|Li1(XaKI~>ytmweLvhH7Tg(Rkp)%3Bn zKPPA!yUW`BSpPn8JxdKy7vN9m8C(BYy~On_`WkEsKk|R3p{~}=PqfZo?wF=VN0D@H zgQG}Hq;x;y#V3|Qepjws$Cp=&ee+p9J0{+FjOAN{o*d!78!Uy}^;PMA6Meg}{%pCp zwHwO?%B@RT0mCW!sw-oWteRC#FZ>sY9zhR+n^c?|$$s_|EY;tHv9N*|F8yOSv^ia0u3^e}VJ|Zz`ZBzD{HFxb@?3Mp80Xz$g zSm(cB{Y19ex_W&Pd(nDeeNXnXwS9dD_WOdTJFqQQ$EW8N+y{p1YiY>1IKP+JZx)yv zCA4nCuBU4g!jv|H=6(fJmqlB!t2NeJ*3evc}gcYjlf)@{ZEh1s{hVNfo$igH%VaoqH{8RL z1Cg$4Wi987k(=DCQ|;JY!}Z#Ak|K5LY3s5p`689}##M5|ryo+4td1{b zI`mdAjG@=`;J z*{K8ZL-I!?#F0EE4Rc;ByCYQWjT@9R)MIO7SvrsO4@R@Yrr7#)>*N$0ws(QV+;HhX z(wJe7*M`~jaZqzeVy(9Be)T>$iu~8QHCad1oTr$uBv20i1#8@E;XEocy8}ed{YV|< zR?@fr+Jc6TY_Zj;AuFF6Eaf@yaT*p5G;e9B z;e!Py-4tN@v*akHYnIv1t#2DTWi=4C=8srBO|?s`uCKSwor~VgfW$ZFtf$OT0_m@b zerL00eK(Wi(6`WlOSun}l$3HeergC#TaKDOlRDJ=O^~Mf1Lyj*vja*#v)*~VEBlA# ze&c*L*Sh$P4q48ejrb3T1zVxYLv_Aa7$Uae9;3p5X4%rr=0lG z&fW&p)7;{KtnWT*u*d=EG_>*Ici!e9QF zE~vQ)Qqlf}>ehgdS zJOG9*t(6d5N}?6t3d-pl$w6S3j$yx@_D4w&OHZh|Bd+EyRnvNKPiq8PFYOtwHX@-m z-tOelH?y1#|3q1fbhE1p=7?LQ6l z?cd+LN>W895G^8_4E^+AMzfFf3{X&{RWAjHXcg_k^h^vn8fA!L*`X*vvFtz;0Q|j6 ztf`;Vvf}Tbx52j0zRyce$(FFgmU^--CljNKlGgt{~%I1rZjOxK(LA~kUt@OtH(Ou-dx70q z4lZL#*W@#+A0kCSROBOTtf8E~(R%c&5ogN5friM~jKr9NX+PqGW&5@h zJ~?W{`$<&C>z?t=DcIWG`udy8B3?hj+WLoMS=&Ilh}ZW;yst0neIqsZ#|h=2&5G|1 z^*cA#wf`RwO_%Rlvz^vu-!+ARZuqV!cPFW>;Va@s&`m!%LDk`A>)F`Sj==;fEeblS z_1kw=xzgh^m1^~YKH1~%fh2ZG4>TJ8HiXY|+KVtCrmD>VyXsC=)%xzxz_wBscz^1? zT}bZc+t+g4@GZ7I+KjQv4i`9H+BQ+^&cg-g+gLu@Ejy{9#u{x*`cG$}X8K){cTu5O zum3>$a`*?*`>EgG0KLEONU1$TCMadL+W(Nk74!txwCq3559gUoz55u_HA9axgB{4#mT{aKM%3b!QQj>{M^(&2XmVZ z*cVhd>Kx3azi0LSCC{G-D3#F$d7q=#BYyqc(P5Dm{J-Sd&m}ups=nLQ#2A5QnX9dP9P2vfpn5)ESjS z1!^`&MftQZDJoIm)0bM0{Z^zN={B_>9%pr%E75`rMD6>nn|gmrprsh@VFgytV0En2tAOGDbc>28qdB|{eA0~WAxCN@%wdP z+@jx|2VUJ+QsY_9#n#T>=`k<&AIt2u1O>B38i-r}2d%33ap!?o@Dg`P()35f-b~is z8h^Y~XbtoV4=34A4(oJQNAFljGS|owTHri)oSu69@OUSm4LW$g&U&i2KG2fh8&T`D za{m=L_4@GsYgzkNPIY2G)-LcxxPyp=8<7xc{G0pVV0gM-co^%=b_kQP%Ty;Gor>Cs zw-M5^W#U}UPGj}r9?q^}E5sqrTH>TF+r`cVu*}7>^XsLsq-3alJjU$MbWqH5q4IK3 zor^x+63^$dPQDyShBze7aI;oTqA}GjdJ=~g85DSmnQoR*uA+`;^L$H(}9#nk{W zaj6HWYYDS_p&55=wo*3-9=r0&)a zil#n>=kG;>&Q1q!0%`2h#F=*CH)3)cGexgNmI5DR{GKh!6464vID|biv6#Rs#FL4v zHE4e~ku@(?GQee1DPvt`VJcMVX7DxU~QCEWs8*o7RpnkV?ET%F8X7Q9srDrgY%+<3wdx134I>TKfICbLoCL~2Tm z>}w?fi^YX0Queb`Vq`xLWyHwlsZ#dWrJh{&2qI&|-Xn3TG|H38-L^ZoF2z3V1c{US z6{b7F&K6gsvt(Q1xaD~=iQ^SDZaPwvgj(sWOi8?_XqUnKXst&Ea~}7HW&n>A{e}!2 zkFOAq<1jNK;hiWWTOE%{~>OUg9Z=>} z>AS?7R;*L13IjD~`%7$X#V(AjJY{7%28pZz=y1Ey%+4b#&q%jmvs!2XqM`yH8i_76 z#PzMgv}c59&4ym4mU%H%Y95he$L6N2q&q{D&o4WBnk~SG_PI)oQRayJ zHsGbAx|3p+)P;`rQq*AbT7f!zI$VujV)6&XBW>6O_M}K@iwJR-xVSAF#8!!i+e#yt z*^y<6FWa*7d{2TzGgXnFRs00yu%AiP*HMv8Jv}}{qn#ts?a{`g&x=K;mm&dupA4h) zleK(;L{7Ifd7WXPquj0y#R&Q?n8$Pt@u**-XHu zV))MgWvk=>(CWrmTI1F0c`9<`4}&E1MX^N0qpyfXw@vjB%@k(3qB*OntZYlNCI%gC z!&HZ_goQNg2y3}pT+oq~z=U8lW93Z+IomjH@E8SGv@6=kr;)h+)PEj0MMaX^DJzCa zRZrzcNj9gfNfl3UqfxK-=M}d*wECP;{;wSHEuGo0FkMW*^?Aqh($QYT12{nNf|ndA1yU( z8qkCC$(mCPGu>Y&-tEfD{dAg%mZP`QUUqJ!E$YS!JdzwyyOdoLsEI{wT8eq)57DO- zTQzUL?v0r>eh`%ahWC+P_)k|i9D~{Y5spnfb+Vu9^qB0oml^`oPV7E+D2%x&fl3L z;(X@`Sk4r&OZMV{TpCSV2HwnQJC-YZu;yVomtyv!!8@}NU4S7=y;C-ls2W+=h#-Zs zLZa9cR_yc$=HSTFZfNx>v7*#8>B&N+PZ4j@;;2#mJSa;NPBI=E&g7n~I{XakmhvJq zgs?o5oY0S(ZAdO4c&>??A32Z$K=9NNH(zuh`GDY|du}dsAccTnAB&s6Y_i*F1qe;B z=DQB02oOBi$<4)^=t(i^zB@n^sF*+e-G;OVgkll%IS0}M5DGWU*|87`D9rc&X4h&D z910oC7aT|qAb7BYn`<3NDj+n2n~(gh{!-O_03hl0?{JW4WYV1<+-NsV5b35Lav<-} zT1E!I`!?7}eE^{;&Rn@c4DQX&My$H9Hw$43+SHphS2r&CqM6pzyIcIpo%?4ArSKj? zQ5WvTu+!LiDbJ!4v%sA9Jbv}MO>0lXRs9z6KvGD!p}Kge=-;2c-MBhlYT1r8296kj zjX3tXxbk#1IdVIL4qY~H`uKFbx|}^I_6%g%;<%^l&S&u%FN%qw{Ts!lbwG!f7%=BUHUUveHf~*%! z&c?RI61rDb*!(%7Gv-=ZQ+2IuCc)LUvcHL$XR{p`SM52hmALsF$r_~31?anTu-o#W zC^?svg_M%SEULB>0kHvySbHw^hBt^E=gQSiU>NHVQg_Tcsml@7csSX)x`O4Q%q|gE z48saRh!w+F%k&qhNsaEA&}MLn_UsGdlVOmw5WeATkHf0x2~DpPIDqNUOwiLx<#T#AEZs_#wZKl##s3L)SI_O8Bt%1<~qq zHnpIh#OGWrt$mR?DliXiA!yyE4VSa0++LYkE5?+wk`zfv(3~f$)rn>0tk21tsJAhG zE@#U^C+(zGVa%!~M`O(lH4*Pz#g2z<6863%Nl>Lm3Y2QE#CNU%)7v`^#X;~Y1G8Gz za&QQ;Jq|+c%!`9iJGC*8LR_~6Qe6y)Zuel7#40XS>#;U z^%x#=>B~gEO^CUI%FQrFvZ+9 zjuod6j@iX**ot5M1@ZhimY?g4+mDwqhIzQs( z^J;)GdsSN%1n+9VtpQp~$o;CT#pSlQ*(zPR`>S?3?*q|y0>j_X5Ys1Mc+ZH3 zC$PKuJO63o?)+|% zF_e(CgybXE9PaT)qGAT_gWxq^__$sDQAN{hh+O?=ao!|0v;Pm0Qm5sqR2eUD(2o#! zJSZ~b+I9I|XaOWfTS=eHTISqAO@^>&!2tta9)$B(BKF|#V%TJs6P6u@;92!ql2Zwo zr{1LwI1z;XZfA@`u=!7D$Egq=!lhSJ1&M@#qLg6oQ7MIOcp&215YEtMnEQz>RY4au zNImbOJYLd=2X|+L#1|j}pa-U~4xRs?%2-3`b0o?17D2k0M_1v&>j)+0O;v_AG@l3) zs?0jygEvhbb%= zj&c+1R7EG_UOeYKxOO2KjcY(B;h~ZTaRmaRvtqE$7sEOzNfAFng9|3O6${1UsjO4Z zLCIRFS1RHN(L(|Ie-;0lio=@&x_{FEf#{cT^|nqQ{@`K25_nji?mUfgN_R zajq+|X$1`i7IB5rBb zE?UV&gcF1k84eeablc6rcSx(oJ3l0{GIiS=!BcvupWa`JmzL7lk5SJAafk455qg&Z zRaX56@rB$yK11{I4h;e*ep20|R2K$j&LMbEbM=QHH2q$pc2JnyD>@>lg+(DGS;QB~ z2BilC;*ew)tvfaSZmK|@NuNt8!$YU(k~-Ogevd52Yepo@ZUkMS4Wdc{knvW5CpIa( zzxd!9X!;3F<0)oIiflO+-vvcc!GN2d9JYsHAOlC}36)Fs%A#hpT15O`A=2^g}3 z_ps@Ky~WI^KEo>|jeGP}6M~%gj~I$UZ<(Z=w0g=Bp}*0rmF(gDvuOnS&y< zyW*@HSoes-PQYkld^UEns_;-Qe5Xwd?a_d5@C8!8mBA>n(|b!xm8+v6C>3yY2Yw-e zD#E+KQ`u;$HZ{~&dPmhq$Y~s{xa?NQDK+*p(s!e&MSqCCH?k&Sn;_fU!dUfx(pc&3 zL6TtG7ZQV%15^a7G;vBsDlr6OqY0553LN?Ki2S*de=Kq{3g@8;G>x826%OC1R3ZB& z)_Q-T`GU^`k|OCy##KfotM9*ygokryq%T5c;#4p zcB`G0zomS8e0H0imA|-i6`$RKEdE@fW>Nxl?6r&S>@GVie@pp+`0Rc=D}TXTJA06R zq3H3Y5{izFsM2Z*+K~kq6C$Qa8~d0luCa@4YzYPS90J2R*`+qJgran=DqUok+Q<@$ z(uJzD)-JV?0Y(2PUaE>$+Ql}ugranXDy_3iZDa{W>1tKF*)Fw_B^0F_RcXClY9mW1 zN}oR#mSbwLi*4-Z?d(=ndApsJ;8HH3sJu;;?u{$J-no)}xcQihxK>)A!ESA?!E^RTlcodqNm<%=;FM;s{=}*pKgdW3-I07|h z&SIx$%jTkZ^tMP2sy?2@M%Z&JcLYnbj5B=_s~7ulkHhj`pMCRT~G0FFmv zm6(_+=%G4F2WY#N=H>}iV%=<(j37n4IGf!`yAIK_gb_=LnVNrxhq>izEbN&SGdKMQ zHvJ-JXb^=Znpyw@c+3X63|19n=+mXomQulRXoeSu=CIrmP9%@H^5l8p@BxhC6 zkeD0~y08OxdK;R|$(a{|Rg6Dj9>$v%AezWf)I6MeF)4r}Cq=f3GZeZ?N5p5?Y^krt zJD1T>WSOIqvQIh_!=}l^+p&fIt{8PE>pnTMPK_HQ4a<%O8Z}GXQj$==Ig;3)VOYV8j+;3gW<*=Bgmzi@B_2`2s)lLL>CsNj5=ZrW2mo`bE*5kih7#_dlO4Ey^H0I_?}En?kh3_ZeS>0?=5$&B;Sy>=atA56=czt;KQP8 zEUcxR)xx3Q#XWbiq9oY{D$MyqY`F`U{_Yh!?_$Ondr9j!5**aPF`4XI-BL~j%%Fs%HL%ke|RC27~72}wmB zED&uw3*Lx-j`8rc?2x#?MC(|xM14JxbqWXXHp5X5j~6{Tk_dX`Sme?VCmQ7A;o(oR z8g&Kb{<@}rNHUrr{f<3=h`i5{&M0gzV5NH?mjOw_Wt=H}hVpG{0f1NLU@$U`?Mb`k zJiHR=zxOL03*?HHc16%~%-RBG0zr4a2YXy4Tfc}?PJa(@WL)A zAdJG<+Q9B3(yB39*5l8hXwj_xKJ_B643WawJ4d9c$3%D@TgZ3Jw8~aCmoE=tZ;QS2 z@is5@-Y=1}0PNT;x-7tv^#|hG1*|muVLd2j`b*?A=nj(p3Z?Xe)Cab>z+*Z}!g%Qz z$z`tmbNm90_a~DuYw3*0Y>W1sS4h!*S$v^+^n-dg`l=HhENqlE$g>1)Zl{AogXgD# zkZKM8oEORLB%1t5z*v;}NFg|;+R z)>9RCZiGro>f&D(4h$kH^DkVV=RC?s42G z{keuGNhCFU$-&NI8 zJH=#^_(XP!X}{VNCM}Nf-$StN71emJOe>8i=MhaQWp~TDSw)lTg<0qPS$*mYw{vL4 zfY}B+Rfm43WiQg$V3d=P3<8`jCe#0n?2 zC!ftSoRUQSLxgJ3D&I0?dpDd+p{_x;VykP|yxzRo(ae0Dmns3O$86;)QCghgg2y3` zgo^kNB6c3cbxe}p4Cu6zhlJch^AFT85^^)jFzH>-&Rn4{By}yIWeQU7)!9Fh&o_T=$ioQqcGHv=vzoqY$c_IpLai)6!j%t(BV*00I>LNDRFI|^BpZ}Zi zJ;*MxpC>^CWIwVw`9T)Mvy}56WDmt5_gpODmo3JlZJWs{QPiaFw2GyRSxz>!Ol}gL zp+|Y0z+Cj9cw;eZKWL|PYj_0@ViTDrC8HZiwX~T?$0jhhm2zVdYe=t}C0Q?3OffUG zWaS^?v?Z+lfNgeL;j^h4z1IgbeJPhv7|KX-zH}PF9ZrnXAey(N3t#)D* z^7@Fn@qw3nDhR#J45tdUl*4;F@b+D5Il8EKUTkD{{y-clpKUT9!2?}|o25YUmtvWb z0QS40uUM0>O%m@u%Epv@gdPk;wHOyQLhP-hUd=8NYBmspc}x=Wnz(8OTgD%ng;{tl ze{fdJn>WvjyaS5EF{_^GWE}G>loqe-6g?hiA>6RL3_q94Hsf#8+V@vwiG3fpmNKz- zd!2i-b+K5R!WxAYQ9uUZVQ#_3R?h+2Uzj0NNz3dYZNDqS}nPDY;p7=u_*Th<=j7qgl|kNj&>B z9wz=qq-zR4?ca-?MOMi}9#i=hAX3X6AB|(eKl?Ujz z7JuIOD@v^6`g3B;-`H1t=MQ4|-`QBc>j$y<@2p+^&L2=Nmqf>pAJ?V^X|Dpa8U7I2 z590XW@mlAdN5p_ltfbw+?}6ytTEi_i!<@eDnk<& zQ>uxs-TFE)`8hV2eIhnJ2LswD_B;oVKSvyWj*Vr16J^h{DvQD*|z1i4e(-t<|s}MwTJzEajTvyNX`JB%; zZL5br<65$5z%l!+FUZ1_e#` zA})JfOxw!N;;SXrfbI?g!fdlTR`h1Q5;dwsmM`E8IcaL7`#;#A?lybr4R(&CB>#i* zX%5V`Ip%v32ks#TM{N8Do2Inp!%s!Yt1P!)L>aIYpg-FPWl$|qlu2xo&!~8*#rN%A zy|FFc_9{HtF0tWNHX*75kU>-jkg;{3?`v$XQZfXGv5o9{jTNW@s7!2uzkxMH>%|Rh zLRVYEz=@N#uBdja*cj839ExaYz;(rK;>QNoLbn+L?NVkSieG07u_Ar(b#Q67*du=) zcmw*rTZGb<06 zb)xo_PI^pR@s*epC#2i`C`Z zIK?j9bGsS1p99xz&Sh2lJ0kgQ)*O$@c6yt2kK#c$8{^GZcu%~|3Jb{LLwD_l@aF|t z2pf;Bu`Gkz{_JgbJ^M&p_72;b@G%jW%tYOG%#pLj@a?#w{jpfJ9pujzuWo0T!EPtK z$MQs zB*Uu|h{GSVv*23#e8PsIzqy|{Itf1!tCP=tf(?v0;*U?*=eR?^z*BLSr;BQ~r!-ClggP5oJQ!o(tBL=^BbPwy18S$rp z!oMrRe1^l!62?RG29bC9Os5`JZSvTK0FPw&c8Mt_>3j;gl~ud|9Y|hYt})u{+tcUh?{3Ik(i5ii|Wr=CVNjD z{uUGMs?S-#uC|V<<%pXO;(7g!8(4{W5vih+GyqARWb&8IUHt`{%Z_gP^$V8HGL;fz zR~pBq(DNjz-o^oTI7!lpaKP;sDW9`5#i#!UMG?a8`8OM5=i0nSBT|6_j;tC74zVB# z9BxImbzdv;F^GxPdyGO$#~Jg`;wGsNZ*j)0J?~|U zlI|=)jQozJ^s1GW-6vL7vkvyRXqH%d5-hR&JJwOnuWyPEzhfi2Ilj0t9kd)F$6$VR z5)4ssh_&+_l=Lm(VpI?4;@U$jHS;@v~6N$;m+2^Iy|$Tk}&5K^m^AXYpu zYd031^qSZg>;@DXWw2Uoewg+BAJ4SnFl)tr+w|gL_A0%_YpI&1b;KtDA1B`o>16Tq zFRZnB?&K-j#mO#+OZ>F?m|~xC-En2Yvv*Gw_=$ z-Z{d?U37KjxM}4xDl|9KWlz^koLD*O+VY8&V~mR`C(Y>8xrfoZwNYX;L3tXg7U9>8 z-&my5u14!Vfa^}VxbF{kk=XttOA1{M_~n34#wQOSCx1^QFOL1lx{Hf{V&{vQKe4=| zf!9}zzGgVIYnSd#8hbOb$OZ-8ef^+%pKHO%usGS5pI zWfu?gh}vK9eC|@QFwHW;yo=EyyJo+2!68_q& zYZsxZB&N{|^0e4|i>t#`IMOQp~$yxluwVzpNsOun0y)X88P{*kuTP|L^})vkQ{?>C-Sib%ttK|9i@{MSb1 zzc(s(@pyu~$j9;{5LceBX{n76vK$04`wuobeM*w9U4a3TP{~N9ByDmZXW5(`68VgG z;jro9j9{!V|u}1 zrid||pO$wf@Ol8RYqGMn3=D_lkLI4|{H&yvDDSQEx{IIR<{0v34E~S^zN%jp$&0xz zUh26cRo9v*n=WwkP@+rMr9!V1gWbGCVpn9FqPdkKj4Z!d7j*2HcIUP+ifNO384Z9FhlX8SF>UO`$=6|& z8n%DDym`_Q6g5GSKV9_k@@B1!bY07ld0hj$HDl7`8OGSj*Gw9tX-nY-=--*?qT0*b z^D*h7&dc*a)03sAgG9QT66{h}~|H{tFK(IbI3%PYuG!@Hnz+@#7$;}pX| zNS_QbC4uMh3o|y&P2e}OwD&TV&-@6#UNpByG)d&MlghJnss59*#EL}RlC4FaT+}-J z5?Nd9-*@m!&iwE;Ud87XeCqM3-SkQ_pYCFHqI(+e zj-SbC`~v*ElEx>WUe{DFG{zGY1QXQWA$ zochO*?$9Vt`r?%Tjx-+Z4aWh3F$iRV?HlE3_)Y_vD38t4loE?i`PlMg?46@)vBhw=^?x`yINg*GUsIS8EVpT*m!w+pKB{`jSih6M4BJKnj?806bh-i`sT zx?x6zf&3!CNeN@{cV+Q=*$i|}cU zPb+*{;?n{j;Eb9)slu2%*67*z86VwlQ?0>!F{}YU z3G&mqRw9fL@73PjUe^pX-vYnnO)K$n+n)*e9YwyWMERMK?L|$94@j%A>yYvU@u?A? zg!nLQg|=p@IBh$(! zjf2~tG{&f$G^XNuV<+I$?c*Y&C2u?aD6%Blluk-S($RK~1+tYK;d<;N9|ZPTt@VaE}-7Ehfp?hcJvce9LgMp+SKi$~vbqvn=q zHy4kY(xzQeY2k>QC)_w$izJ}WDH{Ssj~QP)rgX%Oqi)us2qhLzBZ_YwHKlCoD9|rS z_1<(#@zgs;j2S;_!el^B@MGMK|2!-@TGKol(|EZS?a{R8=;)Z}7%iH6@WeRB|2*2u zHA3b^Tx@J~d^{>bu1iBv=Rcila-%6(p#$Y^ z7iypJ(jsYQ)w zmCzUsl)Jdg^Cs{h9|J)I53Y#`9!o{?N$aGgZGb<`; zG;g_P?m0_$w`LwZYb|g!ZIl%?X~K5c6#gp!6+pg%6elPKxr`^)y*4u8s>CQo29%PTQ$Jrb|xgR z-trl2I=heE^%TFK&14U-C)jhWcrJT|RkICj3p>K!X4_Z|+s^*V{=yEj_t|IcJ+_za zU|+MN>>Kt^cATAHCz;^S@@M!ezJjmhPxI&a7QT(Y%n$SDc{M-H-{l|ikNNj}5C4RJ z%D>|=Z+;nd%-ZL!WSgvE5xKa|l-IQpgYay6GOYB-X7m)99KN6M#OjIb3{PiVYdn|W>W!vW+D3QBbz1agxNeQ^8-%xs>4WDxVmjfv zF^1~h7enp4y!p5mdWYirke6!M;3fDzd3E{dxuv}R=p&l$@ljdz{9)L0PAtLu#1j7G z*fLzdh`kio8>SXUMHrgt(KlK1rc(WH$m>_~dLS-0`(#B$g=V3@dxq(zPxh(P4I0rYa z#2`?kBombsCmHch1~rtbFSq6;ksS6U1=y3;Pf2Zom6zP29&(mg6Ou0iIZKlV1Ls6? z?+ogd*`E61DlxasqSTU^)YEsY0V!i-w(2zR0i^J5zn9YaLZx$3rw#q`KB_Ml1wp93 zNU=VbSGml%zOl@!A0SBh6_|T?i8-SZ<%&4TX$O+qD}u>wNUp2c@NMdHURxliB+Ee` z1hO)nbm3HbdfFyxz)MWMJHUI#Mi_2`n+(d~&$y#uErCLmXpP7`PGw@5wJW8W^<_pD zYC4c!{jj$Gzr)^Yf0hMEjQ*mjAw#3`HWi>**b<8By|LcqEZuW~QRu zGntKX&CH@}k1T>*lQoW=u-?qND?`ewB?t%kX2pYGleuX+u8`i9*`1OcO`av0GaH>- zVO3>!siPPKUud1o&V)*M8}0}y*D0{XjS^oqycjtxb6N&-)}cN()UG&Zj9-!vq5nu- zj^(E2XFit~T%IK}y!wyUH#wx7&5az7jl0$wY;;ozk4}jc>jlFoP>fBd!uQpxRreZ^ zy<;QMO*9jTn>nft(epL&G|&vwx7&;5uurzYWH~!Ti*ygLW4W z`?~}?w^zazTKNHDNdLe?!5q>NFBoz-&=)x^8r5cq7YrHOXna6Y6r~uF32rd2d9TUP zsnayB%xG}rM59b_B&KnmqA3bY=+?Mxg;moy$`hk>)fba^onrPi%!nuTIF z6!x-Wn{`J&2Q-_2LQl4DXkC&^+BYgUiEWyjo0_WRm4x9%a=~>r6lqC4m?-o}?iy6u zsd-aWII4M@=8gf|tC1!J&EO4wlJYJ9F=U4ZIGDY;`GSxDkU_99EqbG#=UOxm<`4lK z0yxxSgyLx=*xaw>RcLx?%X~-lYpt}rZ0lr8zk@@7Jf%Y@;OJ0lPj*F6-Kr$#BlUIG zn!F5aMxI^PEdiH1HLtTG^SepTcXn}b`o4U{ds3mZ`Gr9`kJ@y0Y1OmIi)3h^9yb4c zM!GIRhL^ zeo;6UD81Sg@v2J8*wnzfq`4lo&K^0>waIVbG)6*joAbzcn=XBsb-axq#p5q32zI~9 z9$N!1BF2cL>A>^=p^vQ%akVhkTJ77l z1(znao0V0i9CF@_LmWQyp~JOwEX; zOQaDi(bsnD%4S%{I}QnX29St>i#TS5HKbEm1QUcWw4Uok!um_6kAuQGC8=IvJ=?h_ za{k%5RWOItf`rwqOIbI2;K*T>sYFGFFwWc*E+OQ2AwDS~*|#_)A!|>Ui3$WuLnNUWg~^u%xFg?#HXBAYPqOasmJ?(G88rr%x}jT3u;++t-3Nr$h&ghojssUmiBdkVg zEu+1Lw3f_fveTX{VtvrFA=L9&&vcL;*(+oP$&nK2eR}n5@q6u;McauCKAW4e*}_#}&k>7+`>?~jupq0^b+`H3S4{1!GzSn&DI25K3N1b~LvWiN>P)}FXjo*qu58Yqm%I&FgRcyrbAzr!r6@RUlua+Iju{vK%;Q{5RjB}n)&c`o>CcEIWTsjp` zP7lPHT5IiB>S|{V9?*oR*7CKpGp*mRRTT%Ue%Ha)&K;f~{kr6c8{K>Ux+bW9*L6J; zB`C_&%=c8L$*qK|QmhY#=fr&|Au$La`jzO`jjq}0M zU|s_wpaV1-^A!g((21>0_ogw|5qcWu&iXcJVbU}i- z+VPpz*-<3HCZh`?Ruhk{!fR8kve9v|K~g344~_P-RS-^gq=dVz?jusNT(yY(UFJk6 zVxOHm#$eBG@Q-Ou1dxi299x7ZG4>ieO$wS*tQ0ia>Rud`Nc?Iq)ypH*Yx*o}Xt7eS zj>#`d1%M5(6~IW)S6d$z7uvOjD=>{4Xsz|YxB~gq+&VNaqg)9GDtJOZMe1v1jcTea zRq9h4g_+;TCxkr`1zy+DItPWDhZVAo5~9m=P+aDL@LH@pZ|n|bdhN!p>}l)g8*?I_ zA;DXRCKgzijVI2Gy{f78+<2N+snHMaOd#%%1?WCOafd_~VY*82WCLd<{?f0)ha4$6uyYW&7<%`lGpkw>!z~4DE?~M z@Z3ep6bILPI9c%8Yh@C{Ivm&N|DyH9D2sZmFSS-Cbjoz5TVbn=lp9Dv{x1nx;Me~* zR~vtlrnfO<{Qs{u)}x>Q^=hM9>T3!9B7V158@ChB^>@?=xnQW-r>T$T=gfShf(D>Z zEw_Y4oC^pJ_ttGd#)VN`ri1DPo|jmO4+P>*DqrR-?OVMb5cXO=M|6dOP3u!DtYZ)K zvWL?$t7w)poVY3X03?naYymG;Fdm*o!)etlTD<>eRw$fAWa@RoP+Gi?LG1`lVUcnJ zKD1HzptE?-O)S9>=;a4ZRPxhwfz?!xh;S3eI$s+ARUz0 ztMll=K~~@Dyfx_22B7lfV`;cnJWAJvkB)L?Akq{wTCOAslPOMo?2bqk3tMv@OJc{Z zryrvk4a%3>fv~j4FyAoVP$_#&hGwqLx_UiyD?Q^_F39DNut2ml{>lSHJ5|74l4Afh znnMjK26<5_Vr%B(*JAnn;Ny2W3N1CmR_ML|hC)Xvg|3ncZLj!-DfFr^g}xxF%XCmf z3Vn3W{cO24d2SQ7NDRE0)gq#+A6Tp*sIp5SK3+kT1)xz3bA_?Ys?l|{wD~h zY~I7?zy?0i82VE9>Gi=i1x!_FVzvK?N@NV5KLOY6^KS`eLt`oXQb8K~sAwL{z$l_= z+BSiGz_|-rKo?ssxEVOh7CeXRu&Q3TF0U%E-dISX!}6+R>%hWLV8t-+q|jmY1J;>^ z6gn)gO0lw+CRqIzQRpyg(H$thZ&53c3|yj3mo;Khn$>)9PFo3ZQScy#IM#-HP_#^;p^s0Y&-JjtEj-U3wZdz3?P;a>}w4E9>bbtHCm=bILNrNXsJF zuU7A6#FQz^I$=ij!m{n z@pL+P<9Wsp>RUWRF=@#&6qBxcrpU2Z5oE#Z*sGtPnGHG~e704pihi6m3<`Wq=66{Q z52ssSJ=-J4nY)t}swVaYU}tD)$iVC!F<9GSI3nb8kr(8f#rk`4i=z$dNpvZ-WItvo^Dh0Cjzfd<|BZKDFZDKLHHrojWh7+VW zclBt`-G*i+rxNAx-_!usZF0HliZ%3wPVA^nApyGa&=esptXN>k1ioC z;aD&sRacwt=g{Y(@VqvCqH{Agh5zusQ&C&%&KH}pDpAu3$54K?Hov%xuc#1gHG7d) zRfzSgStk2ce1MyE@wy@2hafR{6iDANyoXu zp^E?A0~W(JUW~zd;X@b`U(Sw@14AsIieoQtUC492#^0*rwf?A{2+vl!DVM!r&D+$G zZM8n!)SCTf{ekP7R;yQMXFUdX>uZ!gng@ybW|p~8Lf3Bi{MD+ca(XuX<`D(6HJ8Um z_#(aL_D3kQky-O7RkK-T>W-<1fT?iic)JM0Y-Lu+YHUm+-pnX5qRc%KXj4IJfo6G0 zfS2TJTEM;Gm#yX8A!6I()XrL)2wGH`At7};@IyGU!EVi~RXQFk;2R}mon4;~q$o(; z`l42M!$Hxy`T{vun|1vJyBH_n=r`uDe{mES*jIh(WZ+rr6r|ep#FiJ2*#TZWy{Fff;sxZJ13T2Q{Z8)(h5y zA3P45k^W)31}{=E=h&3=un5`o%~tV;J1wWAg8s znO`K`;w*wo&!|^WgPOMi=!J6xiieyeC^=+(u&XWGX7Sxuu!pUycehS)d?Yx6?Myhn zf)Yd;3wP7OwYPR(1lxCJw?AG596sqI^qteKuLm^#zk8$Qga2@&<-@Rz798_U{InsW zx_W0O{n!qx$@~t;{x9bzol((^3)-WiWecvesy|DJeF>r>kzjw}^XX#p3oIbs6zod= zw)FOmtg_Fa|qok1Gw75sPGHg{;6m0Z}mPLg!wYh|5q9bKDP|=5Nyb#fw?orkUf(R zd`a`N3smt*?J8ulb`@O?&d+=vTsL)R)d%Cj+~R<&;|E)KWCD|DE9X!~Lz#$okhwfF zVSXy1NkF;gkYC|PfSVPEx?|E&bEpxhJaVXUxL{luO{s@R1SbWw%%CO(=phbRk%e$! zQZVoEOPCb&{rj3&Cnks@Op6`49kIxrM;ap@Ty~@xp5Hyvqt8RslPvS+^|%Ke%Q^}5 zo4e+PL17R>p@m~|4=N06z&~=co#rry2@!@R5Fa+xs;#;IXcp@PCInezz4MQ*YPTM$ zfO!q<8jJ=lw>0?57)cb6p=8*R#1w>?OO{E92alL}ucVZ|!8X>+%)+dVEEe$2DY>Us z$^ELNCBABgFm20MgJGWZuQRTY3pvnSBeb6>$#ncxunBjl3ED2D`H>lH!cD|EP2Bx; z9-4UW>qfYK@OA50)kLIZ$R;cLXwGnl)(BM*lzxHT%LuAy_M)&}%3`%Rs7ULN_?q`n zT$X;rg?W(T@XVtv(7W|Vd&DS3fk%n3{C}ia`ZrmiDgT>{LTZ854O}$2!$QKk5C8-K zuqp&Vs%nvS`!|J2sydv>iNI+_8Q5cv@l9(qcI=xRTz&s+0UiAESUy{3#U8&RZW9rP zJ!iY?la8ld>GZ@1X_XYe4F^-Z*fI?=95YAa6HO;=hSOv*H^lIQZ@ZyeW#2Zo^$+K8 z+=?;Q3S@1v4u9LIMAAY>Ua`v_npH=@c43Z6j4;q{u2!)aoS`KF7aTP);^z<}6st~! z0E$&dLjd3(Tx69Uqshj`V=b_lbs=VyJItt|vEwAd)KAj-UvMU<#P#zu^FmC`Inf4W$AOEhQ8nM;Z zH>c({bw;d5jaZLav4r#l;gg3(>?}&@8?5E0honnIL;KW2^&G99E&aRH^!lW%Ms4@+ zTB6<3?^NsegR3duw+J>Ir5cV3H5^3^FR&Xf{=TDPI_L>C9CaSE7S4Ux_bhwFMLA4P zGlIhv=tL0uppyDJ^=h&A7%b-J3qA`UC7WPoUR`2kY>Z{}$ zu2|=HP{6ewJenE%P&nr;41N#5yZ$-BAjIt@;^;>GtXofY5^J|U{ zM}{;YQVkhEoJb&&hD>c8zHrH)3d@pGg*k@#+rQFKbx3V)b@`3LiT}rvd*fN+>BDC; z;z?nY+b7Sq)Y^EqD;)NBX9r{3uGjAcu-?;tUjf`LUl~@1Kia6%iBO@vbmZHJ($&it zSeuonqyfbi%cFnvxA!7EUBx#NSD6bO8K)f;@nPu-i|nT!=HoN zt0Musr5?ERwe3(=Y>Ak0IBDAi`f49BR&}}TdOZ5>Cpu!gsOpK~c*XAHCw4NN{Sc9i zb!jCBf$2u+TpWMw9orNq&|@4GHobs1^MWR9B^n-mg_y#ab3|J;;nA0i=NY@UlM~a@ zkz*C~#P^QHIrVrW#)ws?=Q4~~e;ft%F@Bt>!uq#eX;+Teb(5&ztbtF`Lv4EW#bO0# zx#~>2srhj((`~Lo5f|wAlCySE3b%lGCdxB+a^u^5K8E5yA9!*pJ} zW}yFRK$Ohw>19nF!-lf^X*Y_Z(qIg{7i;Ha&UVnwiEWj((=$eyGx4DABijC##cgvK zEN&Y_pDM3RxcJ`7x}dWKJ~j?r7d}>G9{_jL@dBwV`+ckx@+wonDSs@xD~LdcdSak5 zFT^q&p%Z_`h7GgXunIBInYF2GfS4J_a5z|OiDMb;Q!%&!>kwV}EUA!N|5nUtz}hNt z^#Z?Q(%5yu%wu9w8Z$))oy9>^(C1V!Oh+AC#ECR!hy?^+A)eJ)Gjw66&KfmWg29KUbut@?TWm_0 zAgk<7T#@1ka!#-lc%4GB!=EZ;cuQ(nC&FZiFf~kk9o1N>S9_i5o@Mgm=CYJz}dl2xu@z|#C45Wj&tTlzJAbvjJ3~bK#p3>L9z4a z?!p3D?W2(MULboh3)|x2p~kFnT4<$FwTUZCq&`o))0ho`*s`0j`_6}STx@E>hQ_@~ zwmrCNAsRMiX}z6ko3l;{D~SHoTBo$l=LImtT}@dpwoYtm%6imZ5_Q$HXY5p@_Ka&a zMSI3K{cly&Rt(F9ZFpL|nakQn@1t(`HD9dQ+JdF{c03LC(t;c}5id1oErJL>iNH5L zEygv6q24DJH)jn|OGQhWI*F7RmB$*0T?F4JdbPl?St;&p0WY{uyxO8pc5KT!fKdQI z`|RpoZYiTYq*BH0dGN~nM9aK$K+E$`<|$E=7uFH3I?hv90fPQJ&CtW=Qq5 zb*!pRL9u%hOKl!pR1LPUqb{OS7m-uQaMW3JC}iy+n)h3?9QKm{3)n zy#guB+%AEsK_Ipen7L5`lY>B#3&67_I7a`1DxkMia6S*)4Rk<-n~PK?o^U2*B_;IN z2`>ZZ5dJD#6jcTAe`m$(1*}Wp9ELrjL>pq5NG}9`gB_Vt$Z`@+Nqa!&8`K`ySE8zr zm9kaB*M{{&Z?A5{`mpE3k~UKDcei21<*Pu68DBrm)1RSCET0n1>j=}P*@y6idOSmx zK2MKpm7X158gB|x=|c#h@Rbq$f6(|36l*z+!^cwbzsdOPJdOWdl1}d|fb?T>MP0F5 zzQc>s@5$1!<@Gmy{^IbB)c7JtQdVLMr{$g-V~0nLsps z<+Y`QvLObYUkKPhqegbfdVKYhxHr_u1==V-efiv&;VN*Ufeb*r^u<9iS_reR^zk6N~3B0uY&c!IjOAn80rs+%iFVjjDL*yWMQ>u zSDb5*&(b`WR*CBvWYUHU8vmnp3yK~cSOa+mMtWn%Nu1B(lPoXTz&RE_WS`GpFonk9 zu5(EHuYAQ_9oe9AI>CVt-Z)Nzwl#y6$N^#uF!Kv(@I&qd{XEy5NFOsp)|nKn^FltR z(|_({#C@GGQQj&~+_n2v`5xML=CDUtAn?YiBM-aChaj0|dl9%2oJ7p!9=%e;b!G)V zxp7WsJQ!vZ%SJ=7s>KJRSw`0*lp_yl&~Z#0tkd_Y!x<*M9Jz>E)VxhJEP61wr&!I& zHZ=3dTCuY;8|9@vs6U^`w)rSK18CBd#OynBwgQ66~wCN1LB^wtik0c352yZ zI(KqH)_;K_s<^~`DXiS_u;;IZuN!MK_^BF5qJga!^l1}mQvM4Kc&r=iQ2v~%H9SgD zZmX8X+(BsJZp(3QVaB_}JO|5hZu?~`5s+ma|7+lb9ky+{p*w4&;*Z$c29C}h(fEB( zRzhq0sAOIpf)vV1iDJ9ja6b=L(Xm;DwfekR4mCwZ&l6h`Y7wFeFO)e^^>l@LGN}iv zDBpy#I2ddOFda!Id-h|s4M_(C-)!OLXAUF_5Ukd4^Gyem2?$CwE_;sIp!MO3W7>NIW1EXqZoJthrA0-UpC$7Y{f{)H4bQ%wrqustF=3 z{!$0Bljd+T>_7C9jnoAY@}K6amqhQL>@o!Cb9=G?9N5b}S);I%uUu4GWpnX9M*S~s zyoUT*FKmbbz1ih)uc8?<%bfi>?)uv5)xFtd*0?s1#-ipm*VTrKZhhH@b&F^8!%|IM z;8p!u6k~rEH(bKXf~Q<)f2+EB?bZgV;WBhl!W)QI1DxlM z4(O>MsDao&0F##mB6%Rok0cWH7ewEI>=1jZy7?fieY5$h_Su8kpY}5iBD`o4jm3wx zm$UI8E$s@1w*o|`E3l%rNldtcwNRb#n>%EcYsK;_Scfi>Noy28aMaIZR!N9+I@W_# zi*@JVD9AdIawQgP7SUP0oJOw^onc4$vei+(N`lh@vWBDGJg6b!RV%G&-@n0`xh+C#;c^zhc z;h+>@U5ANjEztbynNb@eCZ7x1e=g{f8_p@X=>~Rhow{ZWlPU*#QpDzA&<)wReAb0) zI3q>uIvi`k5}qvP40mcx7Viwl#~9~Rmy)BQ5O`Z50v#?J!3u%Bd;}YY%s)q9Ph*Yf zG*UK$m+h}Z-lmZldkaLfQLF%YLq{Q)SRiJO!g9$1@y00jG<%t1j@Gd|h|lJ^K}Tj6 zDJP0h{_U9K;AYWy47(|73yILyaI@+SYADM*^`;bT_4+aF1$U%OtP!Kfv-~(oiQk+p zi>(z)$FnZ=S5aeQ{5YO1s~@9EVN|c1z_M7m-SWX2*|I(2;-G*BC7N^WI@)lVr)oi> z0I86r92|n|ss*8XX4isHJyl_l92{>3(z-AZ9i75i7zGg}rC7@U7{rl!WBv1qQdZtd za>h9z9brV6OSTgEHX-Ip$~Rk>yCmLb(Q_i?{km8`5zFcy3pRuM0JR#855zt*lAfOsX<~IRGXT^Y9Sz5VlFaVnLO3A4xc$Zz&04IX5KJWCgKL{tZKPVG}+ok`h(13)F zB9~yh2}a=-UM0CTfE~SQ<|D+G62FToq?Tt;I)E=P8SZHTaRfvFB>uRSwQln}mBz$J zzfaOkZyD3cMS5!h%np)b-c@2~mu3=WV#ICegsPH)YBY-faXkDc;w~O2#L93!R@RtZJuPh)HoGE1ZZFNkzd52+gZ~F zl3z5z1jDB3lIz5D(eMtI)<$X_@?6tyviTE$FsB8g%yTPs8&Op0_&b=PgkaulxNf_t zNC{cCU@HuDPHGrN5mjgK(m<4>LZNQTLs(Lbkzw6*g}TXWs}UkEBXU|G@}}M*>Q0tI z{cm_DYndx~0y7j<1WgBf9G&vJ=$$h92%l#vQ7LW$b`u91`_B@aCdXg^76ue^q)Ljd zce0!jG9S$3gAnO~;R~pClJljo30T7>zN4$s>;$w@Xs&G|@GfcSF{sKgA^03agPzv@3@nx%YM#3hU1~N&X!&m`o_Z0*Lg(^q2i)LU!5%{4h^lGZa z#-rP=4z@#%>T+~}kkwGPM@0zD#;eI_4r+y zS;QrPWT%Wk73E_rnX4uFnv1%s>5me%eZKq8Xy5KSU^Gi}Z)- z$&g=;l=R3t^+#mB3qmFu?MhHN>L5BK0Ex&FaAEaX@xk4!S(kI_#9=H{fUg}(>If0! z`XLY(=vVt8Zu-&{C>90xVDL-AF+_qg4n&ul6H5HD|3Fg)4QFPRpbbwcIA$O>B-)bx znE{VN^v4(;%&wG0)@)_MtM00>-xq4eA1f;;mrl)(Z*5Ue?bhO*0!DmkK(|L~D?~y$OKPIr6Z9A!0-hqw#6Y%6 zGhq|@m$OD>8zz^t-sMVi!C{QhEXw9D&PLh-@qp{lbI26q)g}RBDL90p(CtVmalG?U zQtIcbDJcj;>!U1*9MO~_5B@7TpV$cABbD?`KSN2VmvXe4zDxA0VC{n@HwwK8v$}AE zC3ra**3YJe)=j`GjB{J|LCXb98oAPnQ5Tfh9TmcukD`Jw2Czalni^PCQMojHs*QkC zIT;bVmilanw7#gShD1p#HK?89$w;Lu_K*wF7g?fzM4bn!>Va+e2%}t?JJkjCOuUnE zNmv)q2;w$mRFG)^Ke^3EKvlp}8(F#^@{CUC5~dp<8e(7upBCUZiL;d~l@uj;IwDP} zDBu_Z7R~%Kr-*N}we?@=uxbX}CEtOv(#=9tc2dSqFxGZ*3Eg2&Ya=iDrCb$Wsj}DA z#+Fc2y;|jNvU6=@2}SNkm0M%y+Q<@$+|4R?yPazzODJ-;m8JKI%F`@FIT7&bE`s?4-OG@t-P)5{f=7QMs#X zBTFc9SE}4~cCL+FF2TrNt+F@S**3O>B6p+8t+8`$WC=y?W|h0$&b5&x6uH|}?k+pm zMwU=hyV~5LviI8AHnxPK@E(fPI zHdVwQp_}cX@E)3Nio;y6-xG3B6tjf6#-KTe(GJAe7L4R!4_UHDh!J78;TmJ$8Xe;Y zbJgB9Zx?JjGOTI5Y77HYDfZ7~nIokagoW_Cf;KJyJ2`-S0PyOyv;U5n71um~8S*SK z{Q=g>c#sSp0&Y#8C7)bsu0cBya9H{SV%Gy~IG^{MD44}MC(8LN0(e-~Eb=C^ei8S~ zVvEMBS*D+Ss+y{}$ycg>)CpNGfG;tSRYW9?xCkG*!6X>wRZer^iy~A}<;VEgA`R)y zh@G}T!B@N_9v068Yk(9&@l04O2HH_Z=>;vgk}oeU5o;b|v4~^D=7-pWSbhlG4H&YR z7_52sL@>AdM2HGR;OXffSogE^=pc$%BPYWE{$>MR1}pJ1wCU2POG%+SG_eyW9%ku7 zlxvgyQ$7sukx&otYt_{_6JSat{TycnrKVM48bbKhq-A*KE780(FD7qyfg)xs6ROH zs8$t=DD(wqg?~0nY8!@~kboFIy&ED%jH6&8SHVyDHDC^8uQ7|Xx*eiDnH_~=A( zwrWuzDB1b{I`!b^RS+f>ME2^xSCXbOmV>&3b^l69;-!*c<^~=8@ALt5)B3;ERT+2I zr*xnx*Phd`L9tAE10`g~8HH?1l)ZW-GUu?2A#$=NR}`6nL4RqcTr{-D6P|6)5_D32 z7ODvrD>&<-dAu{1z({#`4$F;^9t;IAwS8j_&L%!8KAppivGxqtF&o%aff+K{t@>PL zGQeMo!d+O$vnRXE)dLF4?D;eZ#mql|?X95cK?SlFWSz&HyUp^DJ;(PJ97*^iWnZLC#x?|5 zblCHHrl&5y+$z@ePs#X|O50$Yq@cV9kc~6T?HR4K3}h`JNwBM*G#APMs|f(UGlb5_ zXRJZmHD}<%Q5QBTVvD6_p)es$MD#r7&Du!O39aO!`mhNGh6kiwFpsrV6GFLXR#&|4 z;KE6y5ou3g@qVhk91(@dX_Ru#evhqw(M~R2xd<^8tFb{iK4xT3RB7?oQ(}nE=dsKY zavT~_tYNoErIj$^1DwVkE3Dyq$6c0ba z{Db9KGT5bR*lYSulADSwLWJVaRmlZ83?Ae`om@^ILOpXv=-DUWMNW$b^I6ljYM_Qz zo2l+V_)2t%d3T9wl0H>O?)!dm(|p#vfin3#j9C;uoe}HjvqpZ$>qD{ivs5QEhlf4w z5kCU0SfOEb+0*~9?FhqN0xiV2a~3?X_K0Uy8O{9Nr3eRtNqrBsB9Hu#*4c|pq^`e- zdjy-uKdz*YrK!)Sd{7zw!8DP&5d1hG3KwFd`4cg1A&xeGS_6`qUPGn>6KkfwMNj&- z)CiXE!DQM;LWgM&2_MM3Fn*TCd(glzt7wDBY>E1uuWzBUI+^CrpVYX~)>@Ij2n(gB zent^EWqHiZ;F$?nYO2uipV$86&fkb8ZwwimPvql%4~xY2Bh){Go6)p$K`S*9Gr(zV z)Q4rWExE8$S>sZb{SY!^Z`S-zgP^1deu$vJH^{QOV0zSEYLnmcWuUNYnh8uy% zXNy_3TKCuINoh&CC~DUq7qLsQe*dGS41xtSl%bSjgp!)mN)$v2R@pXX<}pR0MXy>* zzctcI;k89FvcV-+RZ1-j(+I>bxGYSI(-C7yXTwZ(f2@Or^gB{MD}^Rg5qeUp?UwFX zg^ub&Vgu?cFZ87>z1*1}U`0{-80q8fm2^Xu#&R>M2ziQ9>{SI#3D)01iQPW51H!;x z8^Lx#kW_qOEmCm{TRNdZNl>*g6_ug?B2^Ji5KBXLplpB`?8&{g6yru|?-AG6+%)~~h5|;hP zGsup~p=7vVOUTxsApSv|&I`iMSfkG)I`w4WL9UQ_duue_kyIm&zV+*P0o@|iypAj> zQ{%&)ArXTqX3&2lgbbv-*D{y$4No1hL1Q`cfw7e^%%fyW^e?1JgGObm^e@HWWq8eD zzbISA9`Q=EBzM_2ipVN9)PA#tj_}BL?8T%i=EwV)k5{p!wUFB{m+)(svo>8r$9}?& zrGg#!YAES1h6czs7f@RSLB{}*#{>Wr+n2LeeJW@wN2`j6N8~eU9-R`}P9q7-py9tu zu1sK-7^$2o>!h+NG=}QzIxD(7#ai|JK^nv;v-~nD1`WbI3VUD@OqJ&Hv&v-J)&5K= zC~5>zmdo{o3bFbrmQ|$eDB;VZIDaH-D+h@Z04oHa3qOO660-Ruuw#|N{}xLUlh-h> z$Xda4c1q;0U~M@($~|2Wi_)hx`RA2Z!}T}#cG=ty9?q>!UCEmB`1vG0&5Nq3%Gbrf zXV_zW;q(g~%xfo(KZ^r$OT~}RvgS?yh7QRSAnH&Dc&{Mz!8hzOR8b0_GQh`{*+Q{v z6;5`^?=L%_bFv$Lq81s4s=Ggj7teB(u<<8*m=Og*xI!PH1EcjtV(0U0Z2n#}U?8T& z*F~ukV)Qy{)VxSS&FzF>o|SaGBSyZ!ma!%CSF^P^q_l1|j_$}0m0lA3?iEMPs$JR+ zhj%6A!g;8oH7wwMAklMK;V!wb(3CA6%tV)GL3)cwz3$i!7CW zDPq?$!!O(2K?oU;8`Pcx2}IKP*pplk`ar&r(7hMbgw|6u-UHfF>nt^uwS{?vo?(il zl7>D1Lo8p5(`5U^pKEcvXM>pdGP{g#KS;?O@!88P#ep5I4ePX?O=OkT&#uRx4sHY! z1BIp9)uf8fet;To>dHiOeQ)(u8}RZUn=Y)4IKfycUf+mQlGDXMH{yN1N|E$3&Z&JS z%$KolCutZUD%at#%LZ{0BsAaqbB#JXf(EuZ&-#nh4KE#7Z%6YubpBhB{|dV({c~U| zaaVjMAL%qRbnz>32mKl2N>NyiH@ByY0oC{zLS^+|su{i@Fx2C@pzSr?XR^fn3e3VCJj?AX0aZe1(I=`qMZ&*!gw#40}}^ew}sex$Ilu;`rD1@?OKt4aW)a zic5cuYQ+XI=5AQI`HG;q<}P`!;^wKN1X#=U*Tm?}?4P{iJ2CJLHjdBuPQ3C4%ge0z z4*7CE{O6y4YB%|51%sCSOd$UL2EOuL@xAErCd<#8cN&P!X*8TpGt7;(ATIOm2y>+Z ziG^>nJ?RJkK_#5yt+AMyDaaZza|?Sgju>jTG*3yawIaKQT@$sRU_1AVyJ~P`vr;Us zVcG4Jjv+K}Ph;G=>DeTa_%^$Q zZ4|@aW+fnV``b9$x?%n{)-hH#3dzV8tNU!j_=`LUM(C@>r+;DFA}L?rE~?&v-c^d1 z-(iCtkoR4-9D{7lyDXEh{(JR%@3Li_A2}it-pAy6_Is=_%Ko^XX#E~b7YpBK@#55b zEQimQIF}_k-`+!SO!}jYZnQJyeRc`o^LJIrq4!yKdj|_~xw$G__GXQeHOd7iH{c5y zbE>J`4%Vl=%~JZhpCc;C7x{N+$vdZ+A4wbx_b?ps(hfFNsmfNxSickUoG#wki35!9i|==`#=6Z1 zsFYHF(QFr+2P3n27npNE98kAEc0th(2xB)3;MQw5?Ck+D5w{j(c1l`n@^6wMOzL?= zyZ4@F;nJ}oarg`5;m~fym!wT=#hbffj1Pz(cC*H~rGF$V>G=@?hXZ2#N3eHjRizGp zg!f_(h?XDY#PI}GCQ9EGZ8b%PrNhyY1i*x+Pn41C*Rod zL^=J9S39!?UuK}pj}ATm`SEA}`oI~DGDVL)Y#r)3y$8oUKNQ|iSR?kEX#ELmpJ^9t z?t*UKjoSZ#3UJm7e;4FKQK|5r{)FXZkwJ&<+6eNGa9~}s8K!XhZgKDvc01cEuKkql z&Hjuiq4g{%2n=C_0d|CxW8mM|wKfXk*?Lj7{f%7@ff;*QLd`#xhy7{TH*uzq^=2cJPf`OP!MC;$7QHL( z-N()X^{)M_BpkIG-+5o?M)eOJ!n^!xe0Z}pF=stXiLsN8`8jz=njiUP_<@J<)tXB2 z&|ycH!If}kym}bRBGbj$!|We8mU{T_Y(B8>IKtimu*W~x7B+qUS8Q~oRHf}={8y~6 zZVyf}xd9^zc6!TK%%7?-i1G5>Iht277|SzXu@1?A0*oODD8{H+$#G!1=hy6OG}7WI zdp<)UAky^W+zyT)AWU>auo0;I#8JE$^1wIjAYXl`dcr?hG>`h0TJf$I-HzjM@Fm|P z@>+F_^+~GbiQ#I@1qTE>EiiXBvHT=E9V6S9Z|;c4kFkDY_-Ql}Y%A_G8*8V+qXl^5y3s;7h@ypiQLNxQMnnC| z@7PG(Hhzbg>VWw2JJvkK)_#{6jnP4B?NpZ~x+RFaRMl)QqKG=}V<@R}C@=>m38d|_h3AEt&NZ zd__w51I~EZ6q%zcvEvNO>a<-};XbztYxOhJOLxmAqt7KQ(_m|6w1az@#jp99`Tt|ToAwK9%6_Tt{tJ7H z5Bf=VM!oe4L-eyude7X>5YtxFXx?MD4=kIaX_~INaGhLy+lX=U_QVm zO}KIDsA9gJqpjC?}?B>_cN;qJyg z9I2?S(QGr|x|1(vNAj!lif^A%Hg(#~t)||*A6Yjbvkbos{G9Zo!L<1Och+81{lQ|y z%s*I$X!{4dLLB-7{Mz~l`-AV~)m#5$b6L!6w<2S?TO3N}sWCN3$D@{=Zh@n?88HX# ze598%-Von+t6{v1-7N|@FXi(h#8S??(ft7DGg+w^>*C#UTj}B#m6t~9+SRBlhH3QW zJ}o@mI4tc&e)F(&F4Dvr2fwgRKBZH`^4rzPr*y8Sl?N+m3jndnsjw5$;SKadIxZ~# zQly*JNhgM-2O>W@EIk70q_FfPq?>COg&HgeAT|u)L8QY8n1gf*y$rQJHK4}whqGS+6dYYb@G3$lmC02d>5}x zP$bgf{P5Mv&%|834nm59AZA4Jvcyx-x;6|QB%#tEITc+U5yewEn z-YsK0@Hzl*qfZU9By@-5kLuot;g`hZ#_1GwQaZuQuV`^M(ql# zA}U_j8pts%vVA-deIL@K(7B?YkGGEAh-9`*Rv^jG#*6hn-VGmWIOXFx>?)zh@=P{O z(jLHByv`YK=Ql z)!n`i!kvl_5e13-?fkZ>x|WV)-{Q%|Qzwj3%_2P%aMHb=qo$1+Z$qaDBZ-&uWvOC$ z5`RA6YoKeF0%aTq6}3F5wD;7hxNicSIP+QqF)5jsL?@>yIECNVyb4J&hGe3l4%#5}>N5QLRPZRxzMS3$PYd$OK1;GOh6cn*Z6EAgC%U(Z{{jVqpNOt{$?2S21~HQBoOFr8m3 zc4ly$@68s6GWe%_b3^fJCht_fxuGI)Axg&J=cHf3vk{iA#&f4S=_X<6pYTkI) zXUx-TrAb?y{NM3hMD{uy;15Hf@z<(On!4}cCnG;RO%5d-pVHy^u}G7kobo=IpBw_j z2MdUZY#zv%V(1#Og9Tb3pHv#0GqZWC#MO3w4er#?Uky>2&D*p%f^s| z1i!}k0e58C|FnO1l|%kR7~_G|HwLBSYz<$fr>UJgzaZE1mZe z-!|oqnMdf&_+5$bw@_oe4=N+)@_q}kv>AUgdPYk%2*!(xbNTiB?=7pB=kiXBwG;cB z^Ip6nPxxE#POWC-L$^_ECGKQPC*bF{f2FvOghi;xQ)eDPol-ZR0|N|hny@#E(a z`&;lqY?8=p$$!GFaUSoLxT>`>>N7o>)(}XmT8lgK$V9ak&*kx+&65jMgH3U#F*0@3 z(?AHsa~lyeM%K;54XcAktvj)Ta7)YyMP3U_u9-q8n+T= Date: Wed, 24 May 2023 14:19:54 +0300 Subject: [PATCH 013/164] Making clippy happy --- .../shared/contract-engine/src/contract_operations.rs | 9 +++++---- cosmwasm/enclaves/shared/contract-engine/src/io.rs | 6 +----- .../enclaves/shared/contract-engine/src/wasm3/mod.rs | 4 +--- cosmwasm/enclaves/shared/crypto/src/ed25519.rs | 6 +++--- cosmwasm/enclaves/shared/crypto/src/storage.rs | 2 +- x/compute/internal/keeper/keeper.go | 6 +++--- 6 files changed, 14 insertions(+), 19 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 489a58857..de1ae985f 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -9,7 +9,7 @@ use cw_types_v010::encoding::Binary; use cw_types_v010::types::CanonicalAddr; use enclave_cosmos_types::types::{ContractCode, HandleType, SigInfo}; -use enclave_crypto::{sha_256, Ed25519PublicKey, KEY_MANAGER}; +use enclave_crypto::{sha_256, Ed25519PublicKey}; use enclave_ffi_types::{Ctx, EnclaveError}; use log::*; @@ -76,6 +76,7 @@ fn generate_contract_key_proof( sha_256(&data_to_hash) } +#[cfg_attr(feature = "cargo-clippy", allow(clippy::too_many_arguments))] pub fn init( context: Ctx, // need to pass this to read_db & write_db gas_limit: u64, // gas limit for this execution @@ -84,7 +85,7 @@ pub fn init( env: &[u8], // blockchain state msg: &[u8], // probably function call and args sig_info: &[u8], // info about signature verification - admin: &[u8], // admin's canonical address or null if no admin + _admin: &[u8], // admin's canonical address or null if no admin ) -> Result { trace!("Starting init"); @@ -256,7 +257,7 @@ pub fn migrate( env: &[u8], msg: &[u8], sig_info: &[u8], - admin: &[u8], + _admin: &[u8], admin_proof: &[u8], ) -> Result { debug!("Starting migrate"); @@ -302,7 +303,7 @@ pub fn migrate( let admin_sig = generate_admin_signature(&canonical_sender_address.0 .0, &og_contract_key); - if &admin_sig != admin_proof { + if admin_sig != admin_proof { error!("Failed to validate admin signature for migrate"); return Err(EnclaveError::ValidationFailure); } diff --git a/cosmwasm/enclaves/shared/contract-engine/src/io.rs b/cosmwasm/enclaves/shared/contract-engine/src/io.rs index 84ff98b4b..70199cc92 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/io.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/io.rs @@ -128,11 +128,7 @@ pub fn calc_encryption_key(nonce: &IoNonce, user_public_key: &Ed25519PublicKey) let tx_encryption_ikm = enclave_io_key.current.diffie_hellman(user_public_key); - let tx_encryption_key = AESKey::new_from_slice(&tx_encryption_ikm).derive_key_from_this(nonce); - - // trace!("rust tx_encryption_key {:?}", tx_encryption_key.get()); - - tx_encryption_key + AESKey::new_from_slice(&tx_encryption_ikm).derive_key_from_this(nonce) } fn encrypt_serializable( diff --git a/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs b/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs index 3c7c488a0..c083162c8 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs @@ -383,7 +383,7 @@ impl Engine { self.with_instance(|instance, context| { debug!("starting migrate, api version: {:?}", api_version); - let (env_bytes, msg_info_bytes) = env.get_wasm_ptrs()?; + let (env_bytes, _msg_info_bytes) = env.get_wasm_ptrs()?; // let start = Instant::now(); let env_ptr = write_to_memory(instance, &env_bytes)?; @@ -409,8 +409,6 @@ impl Engine { migrate.call_with_context(context, args) } CosmWasmApiVersion::V1 => { - let msg_info_ptr = write_to_memory(instance, &msg_info_bytes)?; - let (migrate, args) = ( instance .find_function::<(u32, u32), u32>("migrate") diff --git a/cosmwasm/enclaves/shared/crypto/src/ed25519.rs b/cosmwasm/enclaves/shared/crypto/src/ed25519.rs index 9360cefba..bc6b8d394 100644 --- a/cosmwasm/enclaves/shared/crypto/src/ed25519.rs +++ b/cosmwasm/enclaves/shared/crypto/src/ed25519.rs @@ -27,7 +27,7 @@ impl Ed25519PrivateKey { self.key } - pub fn as_mut(&mut self) -> &mut [u8; SECRET_KEY_SIZE] { + pub fn get_mut(&mut self) -> &mut [u8; SECRET_KEY_SIZE] { &mut self.key.key.r as &mut [u8; SECRET_KEY_SIZE] } } @@ -47,7 +47,7 @@ pub struct KeyPair { impl KeyPair { pub fn new() -> Result { let mut secret_key = Ed25519PrivateKey::default(); - rand_slice(secret_key.as_mut())?; + rand_slice(secret_key.get_mut())?; let sk = x25519_dalek::StaticSecret::from(secret_key.to_owned().key.r as [u8; 32]); let pk = x25519_dalek::PublicKey::from(&sk); @@ -83,7 +83,7 @@ impl AlignedMemory for Ed25519PrivateKey {} impl From for KeyPair { fn from(value: T) -> Self { let mut secret_key = Ed25519PrivateKey::default(); - secret_key.as_mut().copy_from_slice(value.key_ref()); + secret_key.get_mut().copy_from_slice(value.key_ref()); let my_secret = x25519_dalek::StaticSecret::from(secret_key.to_owned().key.r as [u8; 32]); let pk = x25519_dalek::PublicKey::from(&my_secret); diff --git a/cosmwasm/enclaves/shared/crypto/src/storage.rs b/cosmwasm/enclaves/shared/crypto/src/storage.rs index 053ba50f0..1467b5f1e 100644 --- a/cosmwasm/enclaves/shared/crypto/src/storage.rs +++ b/cosmwasm/enclaves/shared/crypto/src/storage.rs @@ -57,7 +57,7 @@ fn open(filepath: &str) -> Result { let mut buf = Ed25519PrivateKey::default(); let n = file - .read(buf.as_mut()) + .read(buf.get_mut()) .map_err(|_err| EnclaveError::FailedUnseal)?; if n < SECRET_KEY_SIZE { diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index 9f1c3fe6f..09c84853f 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -912,10 +912,10 @@ func (k *Keeper) handleContractResponse( logs []v010wasmTypes.LogAttribute, evts v1wasmTypes.Events, data []byte, -// original TX in order to extract the first 64bytes of signing info + // original TX in order to extract the first 64bytes of signing info ogTx []byte, -// sigInfo of the initial message that triggered the original contract call -// This is used mainly in replies in order to decrypt their data. + // sigInfo of the initial message that triggered the original contract call + // This is used mainly in replies in order to decrypt their data. ogSigInfo wasmTypes.VerificationInfo, ogCosmosMessageVersion wasmTypes.CosmosMsgVersion, ) ([]byte, error) { From 4f9ae7e7dea8d10845e02497d084501cd237349f Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Mon, 5 Jun 2023 19:57:08 +0300 Subject: [PATCH 014/164] Lint --- app/modules.go | 2 +- x/compute/internal/keeper/querier.go | 2 +- x/compute/internal/types/keys.go | 2 +- x/emergencybutton/client/querier.go | 2 +- x/registration/internal/keeper/keeper.go | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/modules.go b/app/modules.go index 12732a7c0..b86531fd5 100644 --- a/app/modules.go +++ b/app/modules.go @@ -32,9 +32,9 @@ import ( ibc "github.com/cosmos/ibc-go/v4/modules/core" "github.com/scrtlabs/SecretNetwork/x/compute" ibcswitch "github.com/scrtlabs/SecretNetwork/x/emergencybutton" + icaauth "github.com/scrtlabs/SecretNetwork/x/mauth" reg "github.com/scrtlabs/SecretNetwork/x/registration" packetforward "github.com/strangelove-ventures/packet-forward-middleware/v4/router" - icaauth "github.com/scrtlabs/SecretNetwork/x/mauth" ) var ModuleAccountPermissions = map[string][]string{ diff --git a/x/compute/internal/keeper/querier.go b/x/compute/internal/keeper/querier.go index f20d8cc6f..8f8a943fd 100644 --- a/x/compute/internal/keeper/querier.go +++ b/x/compute/internal/keeper/querier.go @@ -19,7 +19,7 @@ type GrpcQuerier struct { } func (q GrpcQuerier) ContractHistory(ctx context.Context, request *types.QueryContractHistoryRequest) (*types.QueryContractHistoryResponse, error) { - //TODO implement me + // TODO implement me panic("implement me") } diff --git a/x/compute/internal/types/keys.go b/x/compute/internal/types/keys.go index 179dcc05b..2218c5a01 100644 --- a/x/compute/internal/types/keys.go +++ b/x/compute/internal/types/keys.go @@ -33,7 +33,7 @@ var ( TXCounterPrefix = []byte{0x08} ContractCodeHistoryElementPrefix = []byte{0x09} ContractByCodeIDAndCreatedSecondaryIndexPrefix = []byte{0x0A} - RandomPrefix = []byte{0xFF} + RandomPrefix = []byte{0xFF} KeyLastCodeID = append(SequenceKeyPrefix, []byte("lastCodeId")...) KeyLastInstanceID = append(SequenceKeyPrefix, []byte("lastContractId")...) diff --git a/x/emergencybutton/client/querier.go b/x/emergencybutton/client/querier.go index 50861448c..054573679 100644 --- a/x/emergencybutton/client/querier.go +++ b/x/emergencybutton/client/querier.go @@ -14,7 +14,7 @@ type Querier struct { } func (q Querier) Params(ctx sdk.Context, - req types.ParamsRequest, + _ types.ParamsRequest, ) (*types.ParamsResponse, error) { params := q.K.GetParams(ctx) return &types.ParamsResponse{Params: params}, nil diff --git a/x/registration/internal/keeper/keeper.go b/x/registration/internal/keeper/keeper.go index 87c229875..7de1c0942 100644 --- a/x/registration/internal/keeper/keeper.go +++ b/x/registration/internal/keeper/keeper.go @@ -169,7 +169,7 @@ func InitializeNode(homeDir string, enclave EnclaveInterface) { sgxAttestationCertPath := filepath.Join(sgxSecretsFolder, types.AttestationCertPath) if !fileExists(sgxAttestationCertPath) { fmt.Printf("Failed to create legacy seed file. Attestation certificate does not exist in %s. Try to re-initialize the enclave\n", sgxAttestationCertPath) - return; + return } cert, err := os.ReadFile(sgxAttestationCertPath) @@ -179,7 +179,7 @@ func InitializeNode(homeDir string, enclave EnclaveInterface) { key, err := ra.UNSAFE_VerifyRaCert(cert) if err != nil { - panic(sdkerrors.Wrap(types.ErrSeedInitFailed, fmt.Sprintf("Failed to get key from cert"))) + panic(sdkerrors.Wrap(types.ErrSeedInitFailed, "Failed to get key from cert")) } err = createOldSecret(key, legacySeedPath, enclave) From e3ee65d96a9b60b973de13f27a7cbe75c04431ed Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 6 Jun 2023 13:01:49 +0300 Subject: [PATCH 015/164] Register Msg{Update,Clear}Admin --- x/compute/internal/types/codec.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/x/compute/internal/types/codec.go b/x/compute/internal/types/codec.go index 7524cfbf9..2a252569f 100644 --- a/x/compute/internal/types/codec.go +++ b/x/compute/internal/types/codec.go @@ -6,7 +6,6 @@ import ( "github.com/cosmos/cosmos-sdk/codec/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" sdk "github.com/cosmos/cosmos-sdk/types" - // "github.com/cosmos/cosmos-sdk/x/supply/exported" ) // RegisterCodec registers the account types and interface @@ -14,6 +13,9 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { cdc.RegisterConcrete(&MsgStoreCode{}, "wasm/MsgStoreCode", nil) cdc.RegisterConcrete(&MsgInstantiateContract{}, "wasm/MsgInstantiateContract", nil) cdc.RegisterConcrete(&MsgExecuteContract{}, "wasm/MsgExecuteContract", nil) + cdc.RegisterConcrete(&MsgMigrateContract{}, "wasm/MsgMigrateContract", nil) + cdc.RegisterConcrete(&MsgUpdateAdmin{}, "wasm/MsgUpdateAdmin", nil) + cdc.RegisterConcrete(&MsgClearAdmin{}, "wasm/MsgClearAdmin", nil) } func RegisterInterfaces(registry types.InterfaceRegistry) { @@ -23,6 +25,8 @@ func RegisterInterfaces(registry types.InterfaceRegistry) { &MsgInstantiateContract{}, &MsgExecuteContract{}, &MsgMigrateContract{}, + &MsgUpdateAdmin{}, + &MsgClearAdmin{}, ) } From 9b0560f1f9e3e9278d586e4d24572988a85ac543 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 6 Jun 2023 19:50:31 +0300 Subject: [PATCH 016/164] Point CI to the appropriate secretjs branch --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index bedfeffc5..635a62752 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -341,7 +341,7 @@ jobs: make kill-localsecret # next step needs the localsecret ports - name: Run secret.js tests run: | - git clone --depth 1 --branch ibc-hooks https://github.com/scrtlabs/secret.js + git clone --depth 1 --branch contract-upgrade-v2 https://github.com/scrtlabs/secret.js cd secret.js # Use the docker images that we built just a few steps above perl -i -pe 's/localsecret:.+?"/localsecret:v0.0.0"/' ./test/docker-compose.yml From f3b09c752c8baadef9e83cd7ee79e51f440871ad Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 6 Jun 2023 19:51:17 +0300 Subject: [PATCH 017/164] Fill in some missing message implementations --- x/compute/alias.go | 3 ++ x/compute/handler.go | 84 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 85 insertions(+), 2 deletions(-) diff --git a/x/compute/alias.go b/x/compute/alias.go index 70e918170..ca3c4ef7c 100644 --- a/x/compute/alias.go +++ b/x/compute/alias.go @@ -107,6 +107,9 @@ type ( MsgInstantiateContract = types.MsgInstantiateContract MsgExecuteContract = types.MsgExecuteContract MsgExecuteContractResponse = types.MsgExecuteContractResponse + MsgMigrateContract = types.MsgMigrateContract + MsgUpdateAdmin = types.MsgUpdateAdmin + MsgClearAdmin = types.MsgClearAdmin Model = types.Model CodeInfo = types.CodeInfo ContractInfo = types.ContractInfo diff --git a/x/compute/handler.go b/x/compute/handler.go index 4714c9ced..bd0f200cc 100644 --- a/x/compute/handler.go +++ b/x/compute/handler.go @@ -27,6 +27,12 @@ func NewHandler(k Keeper) sdk.Handler { return handleInstantiate(ctx, k, msg) case *MsgExecuteContract: return handleExecute(ctx, k, msg) + case *MsgMigrateContract: + return handleMigrate(ctx, k, msg) + case *MsgUpdateAdmin: + return handleUpdateAdmin(ctx, k, msg) + case *MsgClearAdmin: + return handleClearAdmin(ctx, k, msg) default: errMsg := fmt.Sprintf("unrecognized wasm message type: %T", msg) return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, errMsg) @@ -85,7 +91,7 @@ func handleInstantiate(ctx sdk.Context, k Keeper, msg *MsgInstantiateContract) ( custom := sdk.Events{sdk.NewEvent( sdk.EventTypeMessage, sdk.NewAttribute(sdk.AttributeKeyModule, ModuleName), - sdk.NewAttribute(types.AttributeKeySigner, msg.Sender.String()), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender.String()), sdk.NewAttribute(types.AttributeKeyCodeID, fmt.Sprintf("%d", msg.CodeID)), sdk.NewAttribute(types.AttributeKeyContractAddr, contractAddr.String()), )} @@ -127,7 +133,7 @@ func handleExecute(ctx sdk.Context, k Keeper, msg *MsgExecuteContract) (*sdk.Res custom := sdk.Events{sdk.NewEvent( sdk.EventTypeMessage, sdk.NewAttribute(sdk.AttributeKeyModule, ModuleName), - sdk.NewAttribute(types.AttributeKeySigner, msg.Sender.String()), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender.String()), sdk.NewAttribute(types.AttributeKeyContractAddr, msg.Contract.String()), )} events = append(events, custom.ToABCIEvents()...) @@ -136,3 +142,77 @@ func handleExecute(ctx sdk.Context, k Keeper, msg *MsgExecuteContract) (*sdk.Res return res, nil } + +func handleMigrate(ctx sdk.Context, k Keeper, msg *MsgMigrateContract) (*sdk.Result, error) { + res, err := k.Migrate( + ctx, + sdk.MustAccAddressFromBech32(msg.Contract), + sdk.MustAccAddressFromBech32(msg.Sender), + msg.CodeID, + msg.Msg, + ) + if err != nil { + return nil, err + } + + events := filteredMessageEvents(ctx.EventManager()) + custom := sdk.Events{sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, ModuleName), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender), + sdk.NewAttribute(types.AttributeKeyCodeID, fmt.Sprintf("%d", msg.CodeID)), + sdk.NewAttribute(types.AttributeKeyContractAddr, msg.Contract), + )} + events = append(events, custom.ToABCIEvents()...) + + return &sdk.Result{ + Data: res, + Events: events, + }, nil +} + +func handleUpdateAdmin(ctx sdk.Context, k Keeper, msg *MsgUpdateAdmin) (*sdk.Result, error) { + err := k.UpdateContractAdmin( + ctx, + sdk.MustAccAddressFromBech32(msg.Contract), + sdk.MustAccAddressFromBech32(msg.Sender), + sdk.MustAccAddressFromBech32(msg.NewAdmin), + ) + if err != nil { + return nil, err + } + + events := filteredMessageEvents(ctx.EventManager()) + custom := sdk.Events{sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, ModuleName), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender), + sdk.NewAttribute(types.AttributeKeyContractAddr, msg.Contract), + )} + events = append(events, custom.ToABCIEvents()...) + + return &sdk.Result{Events: events}, nil +} + +func handleClearAdmin(ctx sdk.Context, k Keeper, msg *MsgClearAdmin) (*sdk.Result, error) { + err := k.UpdateContractAdmin( + ctx, + sdk.MustAccAddressFromBech32(msg.Contract), + sdk.MustAccAddressFromBech32(msg.Sender), + nil, + ) + if err != nil { + return nil, err + } + + events := filteredMessageEvents(ctx.EventManager()) + custom := sdk.Events{sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, ModuleName), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender), + sdk.NewAttribute(types.AttributeKeyContractAddr, msg.Contract), + )} + events = append(events, custom.ToABCIEvents()...) + + return &sdk.Result{Events: events}, nil +} From 78656e476466e392f99daace42b3b02ea767218c Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Mon, 12 Jun 2023 13:15:37 +0300 Subject: [PATCH 018/164] MsgIns:antiateContract: make admin a string --- proto/secret/compute/v1beta1/msg.proto | 2 +- x/compute/handler.go | 10 +- x/compute/internal/keeper/msg_server.go | 10 +- x/compute/internal/types/msg.pb.go | 122 ++++++++++++------------ 4 files changed, 79 insertions(+), 65 deletions(-) diff --git a/proto/secret/compute/v1beta1/msg.proto b/proto/secret/compute/v1beta1/msg.proto index bbc042256..c6e3f2774 100644 --- a/proto/secret/compute/v1beta1/msg.proto +++ b/proto/secret/compute/v1beta1/msg.proto @@ -50,7 +50,7 @@ message MsgInstantiateContract { // used internally for encryption, should always be empty in a signed transaction bytes callback_sig = 7 [(gogoproto.customname) = "CallbackSig"]; // Admin is an optional address that can execute migrations - bytes admin = 8 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"]; + string admin = 8; } // MsgInstantiateContractResponse return instantiation result data diff --git a/x/compute/handler.go b/x/compute/handler.go index bd0f200cc..0b2858ee8 100644 --- a/x/compute/handler.go +++ b/x/compute/handler.go @@ -80,7 +80,15 @@ func handleStoreCode(ctx sdk.Context, k Keeper, msg *MsgStoreCode) (*sdk.Result, } func handleInstantiate(ctx sdk.Context, k Keeper, msg *MsgInstantiateContract) (*sdk.Result, error) { - contractAddr, data, err := k.Instantiate(ctx, msg.CodeID, msg.Sender, msg.Admin, msg.InitMsg, msg.Label, msg.InitFunds, msg.CallbackSig) + var adminAddr sdk.AccAddress + var err error + if msg.Admin != "" { + if adminAddr, err = sdk.AccAddressFromBech32(msg.Admin); err != nil { + return nil, sdkerrors.Wrap(err, "admin") + } + } + + contractAddr, data, err := k.Instantiate(ctx, msg.CodeID, msg.Sender, adminAddr, msg.InitMsg, msg.Label, msg.InitFunds, msg.CallbackSig) if err != nil { result := sdk.Result{} result.Data = data diff --git a/x/compute/internal/keeper/msg_server.go b/x/compute/internal/keeper/msg_server.go index b4b1bcb90..4611738ab 100644 --- a/x/compute/internal/keeper/msg_server.go +++ b/x/compute/internal/keeper/msg_server.go @@ -51,7 +51,15 @@ func (m msgServer) StoreCode(goCtx context.Context, msg *types.MsgStoreCode) (*t func (m msgServer) InstantiateContract(goCtx context.Context, msg *types.MsgInstantiateContract) (*types.MsgInstantiateContractResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - contractAddr, data, err := m.keeper.Instantiate(ctx, msg.CodeID, msg.Sender, msg.Admin, msg.InitMsg, msg.Label, msg.InitFunds, msg.CallbackSig) + var adminAddr sdk.AccAddress + var err error + if msg.Admin != "" { + if adminAddr, err = sdk.AccAddressFromBech32(msg.Admin); err != nil { + return nil, sdkerrors.Wrap(err, "admin") + } + } + + contractAddr, data, err := m.keeper.Instantiate(ctx, msg.CodeID, msg.Sender, adminAddr, msg.InitMsg, msg.Label, msg.InitFunds, msg.CallbackSig) if err != nil { return nil, err } diff --git a/x/compute/internal/types/msg.pb.go b/x/compute/internal/types/msg.pb.go index bb806996b..cb4063372 100644 --- a/x/compute/internal/types/msg.pb.go +++ b/x/compute/internal/types/msg.pb.go @@ -132,7 +132,7 @@ type MsgInstantiateContract struct { // used internally for encryption, should always be empty in a signed transaction CallbackSig []byte `protobuf:"bytes,7,opt,name=callback_sig,json=callbackSig,proto3" json:"callback_sig,omitempty"` // Admin is an optional address that can execute migrations - Admin github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,8,opt,name=admin,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"admin,omitempty"` + Admin string `protobuf:"bytes,8,opt,name=admin,proto3" json:"admin,omitempty"` } func (m *MsgInstantiateContract) Reset() { *m = MsgInstantiateContract{} } @@ -646,59 +646,59 @@ func init() { func init() { proto.RegisterFile("secret/compute/v1beta1/msg.proto", fileDescriptor_6815433faf72a133) } var fileDescriptor_6815433faf72a133 = []byte{ - // 832 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xbf, 0x8f, 0xe3, 0x44, - 0x14, 0x8e, 0x71, 0x7e, 0xac, 0xdf, 0x86, 0xbb, 0xd5, 0xb0, 0x04, 0x5f, 0x90, 0x9c, 0x28, 0x50, - 0x44, 0xe8, 0xce, 0xbe, 0x0d, 0xd2, 0x15, 0x47, 0x95, 0x84, 0x5f, 0x29, 0x7c, 0x85, 0x03, 0x42, - 0xa2, 0x89, 0xc6, 0xf6, 0xe0, 0xf8, 0xd6, 0xb1, 0x83, 0x67, 0x42, 0x6e, 0x0b, 0x44, 0x4b, 0x49, - 0xc1, 0x1f, 0x40, 0xcd, 0x5f, 0xb2, 0x88, 0x66, 0x2b, 0x44, 0x15, 0x50, 0xf6, 0xbf, 0xa0, 0x42, - 0x33, 0xfe, 0xb1, 0xde, 0x90, 0x84, 0xb0, 0x62, 0xab, 0x78, 0x32, 0x6f, 0xbe, 0xf7, 0xbd, 0xf7, - 0x7d, 0xf3, 0x6c, 0x68, 0x53, 0xe2, 0xc4, 0x84, 0x19, 0x4e, 0x34, 0x9b, 0x2f, 0x18, 0x31, 0xbe, - 0x39, 0xb3, 0x09, 0xc3, 0x67, 0xc6, 0x8c, 0x7a, 0xfa, 0x3c, 0x8e, 0x58, 0x84, 0x1a, 0x49, 0x84, - 0x9e, 0x46, 0xe8, 0x69, 0x44, 0xf3, 0xd4, 0x8b, 0xbc, 0x48, 0x84, 0x18, 0xfc, 0x29, 0x89, 0x6e, - 0x6a, 0x4e, 0x44, 0x67, 0x11, 0x35, 0x6c, 0x4c, 0x6f, 0xc0, 0x9c, 0xc8, 0x0f, 0x93, 0xfd, 0xce, - 0x2f, 0x12, 0xd4, 0x4d, 0xea, 0x8d, 0x59, 0x14, 0x93, 0x61, 0xe4, 0x12, 0x34, 0x82, 0x2a, 0x25, - 0xa1, 0x4b, 0x62, 0x55, 0x6a, 0x4b, 0xdd, 0xfa, 0xe0, 0xec, 0xaf, 0x55, 0xeb, 0x89, 0xe7, 0xb3, - 0xe9, 0xc2, 0xe6, 0x29, 0x8d, 0x14, 0x2f, 0xf9, 0x79, 0x42, 0xdd, 0x73, 0x83, 0x5d, 0xcc, 0x09, - 0xd5, 0xfb, 0x8e, 0xd3, 0x77, 0xdd, 0x98, 0x50, 0x6a, 0xa5, 0x00, 0xe8, 0x19, 0x3c, 0x58, 0x62, - 0x3a, 0x9b, 0xd8, 0x17, 0x8c, 0x4c, 0x9c, 0xc8, 0x25, 0xea, 0x6b, 0x02, 0xf2, 0x64, 0xbd, 0x6a, - 0xd5, 0xbf, 0xe8, 0x8f, 0xcd, 0xc1, 0x05, 0x13, 0x49, 0xad, 0x3a, 0x8f, 0xcb, 0x56, 0xa8, 0x01, - 0x55, 0x1a, 0x2d, 0x62, 0x87, 0xa8, 0x72, 0x5b, 0xea, 0x2a, 0x56, 0xba, 0x42, 0x2a, 0xd4, 0xec, - 0x85, 0x1f, 0x70, 0x6e, 0x65, 0xb1, 0x91, 0x2d, 0x9f, 0x97, 0xbf, 0xff, 0xa9, 0x55, 0xea, 0x7c, - 0x00, 0xa7, 0xc5, 0x52, 0x2c, 0x42, 0xe7, 0x51, 0x48, 0x09, 0x7a, 0x07, 0x6a, 0x3c, 0xfb, 0xc4, - 0x77, 0x45, 0x4d, 0xe5, 0x01, 0xac, 0x57, 0xad, 0x2a, 0x0f, 0x19, 0x7d, 0x68, 0x55, 0xf9, 0xd6, - 0xc8, 0xed, 0xfc, 0x26, 0x43, 0xc3, 0xa4, 0xde, 0x28, 0xa4, 0x0c, 0x87, 0xcc, 0xc7, 0x9c, 0x4b, - 0xc8, 0x62, 0xec, 0xb0, 0xff, 0xb3, 0x25, 0x8f, 0x01, 0x39, 0x38, 0x08, 0x6c, 0xec, 0x9c, 0x8b, - 0x8e, 0x4c, 0xa6, 0x98, 0x4e, 0x45, 0x5b, 0x14, 0xeb, 0x24, 0xdb, 0xe1, 0xcc, 0x3e, 0xc5, 0x74, - 0x5a, 0x24, 0x2e, 0xef, 0x22, 0x8e, 0x4e, 0xa1, 0x12, 0x60, 0x9b, 0x04, 0x69, 0x4f, 0x92, 0x05, - 0x7a, 0x04, 0x47, 0x7e, 0xe8, 0xb3, 0xc9, 0x8c, 0x7a, 0x6a, 0x85, 0xb3, 0xb6, 0x6a, 0x7c, 0x6d, - 0x52, 0x0f, 0xbd, 0x04, 0x10, 0x5b, 0x5f, 0x2d, 0x42, 0x97, 0xaa, 0xd5, 0xb6, 0xdc, 0x3d, 0xee, - 0x3d, 0xd2, 0x13, 0xf6, 0x3a, 0xf7, 0x49, 0x66, 0x29, 0x7d, 0x18, 0xf9, 0xe1, 0xe0, 0xe9, 0xe5, - 0xaa, 0x55, 0xfa, 0xf9, 0x8f, 0x56, 0xf7, 0x80, 0x8a, 0xf9, 0x01, 0x6a, 0x29, 0x1c, 0xfe, 0x63, - 0x8e, 0x8e, 0x7a, 0x50, 0xcf, 0xeb, 0xa5, 0xbe, 0xa7, 0xd6, 0x44, 0x03, 0x1f, 0xae, 0x57, 0xad, - 0xe3, 0x61, 0xfa, 0xff, 0xd8, 0xf7, 0xac, 0x63, 0xe7, 0x66, 0x81, 0x3e, 0x81, 0x0a, 0x76, 0x67, - 0x7e, 0xa8, 0x1e, 0xdd, 0xb5, 0xdb, 0xc9, 0xf9, 0xd4, 0x15, 0x2f, 0x40, 0xdb, 0xae, 0x6b, 0xee, - 0x0f, 0x15, 0x6a, 0x38, 0x39, 0x29, 0x04, 0x56, 0xac, 0x6c, 0x89, 0x10, 0x94, 0x5d, 0xcc, 0x70, - 0xe2, 0x5b, 0x4b, 0x3c, 0x77, 0x7e, 0x94, 0x01, 0x99, 0xd4, 0xfb, 0xe8, 0x15, 0x71, 0x16, 0xf7, - 0x63, 0x12, 0x13, 0x8e, 0x9c, 0x14, 0x36, 0xbd, 0x31, 0x77, 0x00, 0xcb, 0x21, 0xd0, 0x09, 0xc8, - 0xdc, 0x05, 0xb2, 0xa8, 0x81, 0x3f, 0xee, 0x70, 0x61, 0x79, 0x87, 0x0b, 0x5f, 0x02, 0x50, 0x12, - 0x66, 0x7e, 0xa9, 0xdc, 0x83, 0x5f, 0x38, 0xfc, 0x76, 0xbf, 0x54, 0xff, 0xdd, 0x2f, 0xa9, 0xcc, - 0x4f, 0xa1, 0xf9, 0x4f, 0x55, 0x72, 0x89, 0x33, 0x21, 0xa5, 0x82, 0x90, 0xdf, 0x09, 0x1d, 0x4d, - 0xdf, 0x8b, 0x8b, 0x97, 0xbd, 0x71, 0x4b, 0x47, 0x25, 0x17, 0xa5, 0xb9, 0x21, 0x8a, 0x52, 0xe8, - 0xf0, 0x41, 0xf7, 0x34, 0x95, 0xa1, 0x9c, 0xcb, 0x90, 0x52, 0xde, 0x20, 0xb0, 0x97, 0x32, 0x86, - 0x07, 0x26, 0xf5, 0x3e, 0x9f, 0xbb, 0x98, 0x91, 0x3e, 0xf7, 0xf8, 0x4e, 0xba, 0x6f, 0x83, 0x12, - 0x92, 0xe5, 0x24, 0xb9, 0x48, 0x29, 0xdf, 0x90, 0x2c, 0x93, 0x43, 0xc5, 0x5a, 0xe4, 0xdb, 0xb5, - 0x74, 0x54, 0x31, 0x06, 0x0b, 0x29, 0x32, 0x42, 0x9d, 0x21, 0xbc, 0x6e, 0x52, 0x6f, 0x18, 0x10, - 0x1c, 0xef, 0xcf, 0xbd, 0x0f, 0xfe, 0x2d, 0x78, 0xf3, 0x16, 0x48, 0x86, 0xde, 0xfb, 0x55, 0x06, - 0x99, 0x4f, 0xa7, 0x09, 0x28, 0x37, 0x2f, 0xa3, 0x77, 0xf5, 0xed, 0x2f, 0x3b, 0xbd, 0x38, 0xe7, - 0x9b, 0x8f, 0x0f, 0x89, 0xca, 0xfb, 0xfa, 0x2d, 0xbc, 0xb1, 0x6d, 0xc8, 0xeb, 0x7b, 0x40, 0xb6, - 0xc4, 0x37, 0x9f, 0xfd, 0xb7, 0xf8, 0x3c, 0xfd, 0xd7, 0xf0, 0x70, 0x73, 0x74, 0xbc, 0xb7, 0x07, - 0x6a, 0x23, 0xb6, 0xd9, 0x3b, 0x3c, 0xb6, 0x98, 0x72, 0xd3, 0xe5, 0xfb, 0x52, 0x6e, 0xc4, 0xee, - 0x4d, 0xb9, 0xc3, 0xbc, 0x83, 0xcf, 0x2e, 0xd7, 0x9a, 0x74, 0xb5, 0xd6, 0xa4, 0x3f, 0xd7, 0x9a, - 0xf4, 0xc3, 0xb5, 0x56, 0xba, 0xba, 0xd6, 0x4a, 0xbf, 0x5f, 0x6b, 0xa5, 0x2f, 0x9f, 0x17, 0xc6, - 0x02, 0x75, 0x62, 0x16, 0x60, 0x9b, 0x1a, 0x63, 0x91, 0xe0, 0x05, 0x61, 0xcb, 0x28, 0x3e, 0x37, - 0x5e, 0xe5, 0x5f, 0x3f, 0x7e, 0xc8, 0x48, 0x1c, 0xe2, 0x20, 0x19, 0x17, 0x76, 0x55, 0x7c, 0xb3, - 0xbc, 0xff, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x6c, 0x4a, 0x85, 0xf4, 0x25, 0x09, 0x00, 0x00, + // 825 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0x3f, 0x6f, 0xfb, 0x54, + 0x14, 0x8d, 0x71, 0x9a, 0xd4, 0xb7, 0xa1, 0xad, 0x4c, 0x09, 0x6e, 0x90, 0x9c, 0x28, 0x30, 0x44, + 0xa8, 0xb5, 0xdb, 0x20, 0x75, 0x28, 0x53, 0x12, 0x40, 0x64, 0x70, 0x07, 0x07, 0x84, 0xc4, 0x12, + 0x3d, 0xdb, 0x0f, 0xc7, 0xad, 0x63, 0x07, 0xbf, 0x17, 0xd2, 0x0e, 0x88, 0x95, 0x91, 0x81, 0x0f, + 0x80, 0xc4, 0xc6, 0x27, 0x29, 0x62, 0xe9, 0xc8, 0x14, 0x50, 0xfa, 0x2d, 0x98, 0xd0, 0x7b, 0xfe, + 0x53, 0x37, 0x24, 0x21, 0xfc, 0xf4, 0xeb, 0x14, 0xdf, 0xbc, 0xe3, 0x73, 0xcf, 0xbd, 0xe7, 0xfa, + 0xda, 0xd0, 0x20, 0xd8, 0x8e, 0x30, 0xd5, 0xed, 0x70, 0x3c, 0x99, 0x52, 0xac, 0x7f, 0x7b, 0x6e, + 0x61, 0x8a, 0xce, 0xf5, 0x31, 0x71, 0xb5, 0x49, 0x14, 0xd2, 0x50, 0xae, 0xc6, 0x08, 0x2d, 0x41, + 0x68, 0x09, 0xa2, 0x76, 0xe4, 0x86, 0x6e, 0xc8, 0x21, 0x3a, 0xbb, 0x8a, 0xd1, 0x35, 0xd5, 0x0e, + 0xc9, 0x38, 0x24, 0xba, 0x85, 0xc8, 0x13, 0x99, 0x1d, 0x7a, 0x41, 0x7c, 0xde, 0xfc, 0x4d, 0x80, + 0x8a, 0x41, 0xdc, 0x01, 0x0d, 0x23, 0xdc, 0x0b, 0x1d, 0x2c, 0xf7, 0xa1, 0x44, 0x70, 0xe0, 0xe0, + 0x48, 0x11, 0x1a, 0x42, 0xab, 0xd2, 0x3d, 0xff, 0x7b, 0x5e, 0x3f, 0x75, 0x3d, 0x3a, 0x9a, 0x5a, + 0x2c, 0xa5, 0x9e, 0xf0, 0xc5, 0x3f, 0xa7, 0xc4, 0xb9, 0xd1, 0xe9, 0xdd, 0x04, 0x13, 0xad, 0x63, + 0xdb, 0x1d, 0xc7, 0x89, 0x30, 0x21, 0x66, 0x42, 0x20, 0x5f, 0xc0, 0xfe, 0x0c, 0x91, 0xf1, 0xd0, + 0xba, 0xa3, 0x78, 0x68, 0x87, 0x0e, 0x56, 0xde, 0xe0, 0x94, 0x87, 0x8b, 0x79, 0xbd, 0xf2, 0x65, + 0x67, 0x60, 0x74, 0xef, 0x28, 0x4f, 0x6a, 0x56, 0x18, 0x2e, 0x8d, 0xe4, 0x2a, 0x94, 0x48, 0x38, + 0x8d, 0x6c, 0xac, 0x88, 0x0d, 0xa1, 0x25, 0x99, 0x49, 0x24, 0x2b, 0x50, 0xb6, 0xa6, 0x9e, 0xcf, + 0xb4, 0x15, 0xf9, 0x41, 0x1a, 0x5e, 0x16, 0x7f, 0xf8, 0xb9, 0x5e, 0x68, 0x7e, 0x04, 0x47, 0xf9, + 0x52, 0x4c, 0x4c, 0x26, 0x61, 0x40, 0xb0, 0xfc, 0x1e, 0x94, 0x59, 0xf6, 0xa1, 0xe7, 0xf0, 0x9a, + 0x8a, 0x5d, 0x58, 0xcc, 0xeb, 0x25, 0x06, 0xe9, 0x7f, 0x6c, 0x96, 0xd8, 0x51, 0xdf, 0x69, 0xfe, + 0x22, 0x42, 0xd5, 0x20, 0x6e, 0x3f, 0x20, 0x14, 0x05, 0xd4, 0x43, 0x4c, 0x4b, 0x40, 0x23, 0x64, + 0xd3, 0xd7, 0xd9, 0x92, 0x13, 0x90, 0x6d, 0xe4, 0xfb, 0x16, 0xb2, 0x6f, 0x78, 0x47, 0x86, 0x23, + 0x44, 0x46, 0xbc, 0x2d, 0x92, 0x79, 0x98, 0x9e, 0x30, 0x65, 0x9f, 0x21, 0x32, 0xca, 0x0b, 0x17, + 0xd7, 0x09, 0x97, 0x8f, 0x60, 0xc7, 0x47, 0x16, 0xf6, 0x93, 0x9e, 0xc4, 0x81, 0x7c, 0x0c, 0xbb, + 0x5e, 0xe0, 0xd1, 0xe1, 0x98, 0xb8, 0xca, 0x0e, 0x53, 0x6d, 0x96, 0x59, 0x6c, 0x10, 0x57, 0xbe, + 0x06, 0xe0, 0x47, 0x5f, 0x4f, 0x03, 0x87, 0x28, 0xa5, 0x86, 0xd8, 0xda, 0x6b, 0x1f, 0x6b, 0xb1, + 0x7a, 0x8d, 0xcd, 0x49, 0x3a, 0x52, 0x5a, 0x2f, 0xf4, 0x82, 0xee, 0xd9, 0xfd, 0xbc, 0x5e, 0xf8, + 0xf5, 0xcf, 0x7a, 0x6b, 0x8b, 0x8a, 0xd9, 0x0d, 0xc4, 0x94, 0x18, 0xfd, 0xa7, 0x8c, 0x5d, 0x6e, + 0x43, 0x25, 0xab, 0x97, 0x78, 0xae, 0x52, 0xe6, 0x0d, 0x3c, 0x58, 0xcc, 0xeb, 0x7b, 0xbd, 0xe4, + 0xff, 0x81, 0xe7, 0x9a, 0x7b, 0xf6, 0x53, 0xc0, 0x0a, 0x42, 0xce, 0xd8, 0x0b, 0x94, 0xdd, 0xb8, + 0x20, 0x1e, 0x24, 0x16, 0x5f, 0x81, 0xba, 0xda, 0xa4, 0xcc, 0x6c, 0x05, 0xca, 0x28, 0x6e, 0x3a, + 0x77, 0x4b, 0x32, 0xd3, 0x50, 0x96, 0xa1, 0xe8, 0x20, 0x8a, 0xe2, 0x21, 0x34, 0xf9, 0x75, 0xf3, + 0x27, 0x11, 0x64, 0x83, 0xb8, 0x9f, 0xdc, 0x62, 0x7b, 0xfa, 0x32, 0x8e, 0x1b, 0xb0, 0x6b, 0x27, + 0xb4, 0xc9, 0xf8, 0xbf, 0x02, 0x59, 0x46, 0x21, 0x1f, 0x82, 0xc8, 0x2c, 0x15, 0x79, 0x0d, 0xec, + 0x72, 0xcd, 0x48, 0x15, 0xd7, 0x8c, 0xd4, 0x35, 0x00, 0xc1, 0x41, 0x6a, 0xfe, 0xce, 0x0b, 0x98, + 0xcf, 0xe8, 0x57, 0x9b, 0x5f, 0xfa, 0x6f, 0xf3, 0x13, 0x9b, 0xcf, 0xa0, 0xf6, 0x6f, 0x57, 0x32, + 0x8b, 0x53, 0x23, 0x85, 0x9c, 0x91, 0xdf, 0x73, 0x1f, 0x0d, 0xcf, 0x8d, 0xf2, 0x4f, 0x6e, 0xf5, + 0x99, 0x8f, 0x52, 0x66, 0x4a, 0x6d, 0xc9, 0x14, 0x29, 0xd7, 0xe1, 0xad, 0x1e, 0xba, 0xc4, 0x86, + 0x62, 0x66, 0x43, 0x22, 0x79, 0x49, 0xc0, 0x46, 0xc9, 0x08, 0xf6, 0x0d, 0xe2, 0x7e, 0x31, 0x71, + 0x10, 0xc5, 0x1d, 0x36, 0xe3, 0x6b, 0xe5, 0xbe, 0x0b, 0x52, 0x80, 0x67, 0xc3, 0xf8, 0xa9, 0x48, + 0xf4, 0x06, 0x78, 0x16, 0xdf, 0x94, 0xaf, 0x45, 0x7c, 0x5e, 0x4b, 0x53, 0xe1, 0x3b, 0x2d, 0x97, + 0x22, 0x15, 0xd4, 0xec, 0xc1, 0x9b, 0x06, 0x71, 0x7b, 0x3e, 0x46, 0xd1, 0xe6, 0xdc, 0x9b, 0xe8, + 0xdf, 0x81, 0xb7, 0x9f, 0x91, 0xa4, 0xec, 0xed, 0xdf, 0x45, 0x10, 0xd9, 0xaa, 0x19, 0x82, 0xf4, + 0xf4, 0x66, 0x79, 0x5f, 0x5b, 0xfd, 0xe6, 0xd2, 0xf2, 0x4b, 0xbb, 0x76, 0xb2, 0x0d, 0x2a, 0xeb, + 0xeb, 0x77, 0xf0, 0xd6, 0xaa, 0x8d, 0xad, 0x6d, 0x20, 0x59, 0x81, 0xaf, 0x5d, 0xfc, 0x3f, 0x7c, + 0x96, 0xfe, 0x1b, 0x38, 0x58, 0x5e, 0x1d, 0x1f, 0x6c, 0xa0, 0x5a, 0xc2, 0xd6, 0xda, 0xdb, 0x63, + 0xf3, 0x29, 0x97, 0xa7, 0x7c, 0x53, 0xca, 0x25, 0xec, 0xc6, 0x94, 0x6b, 0x86, 0xb7, 0xfb, 0xf9, + 0xfd, 0x42, 0x15, 0x1e, 0x16, 0xaa, 0xf0, 0xd7, 0x42, 0x15, 0x7e, 0x7c, 0x54, 0x0b, 0x0f, 0x8f, + 0x6a, 0xe1, 0x8f, 0x47, 0xb5, 0xf0, 0xd5, 0x65, 0x6e, 0x2d, 0x10, 0x3b, 0xa2, 0x3e, 0xb2, 0x88, + 0x3e, 0xe0, 0x09, 0xae, 0x30, 0x9d, 0x85, 0xd1, 0x8d, 0x7e, 0x9b, 0x7d, 0xca, 0x78, 0x01, 0xc5, + 0x51, 0x80, 0xfc, 0x78, 0x5d, 0x58, 0x25, 0xfe, 0x01, 0xf2, 0xe1, 0x3f, 0x01, 0x00, 0x00, 0xff, + 0xff, 0x44, 0x96, 0x05, 0x19, 0xf2, 0x08, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2160,7 +2160,7 @@ func (m *MsgInstantiateContract) Unmarshal(dAtA []byte) error { if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Admin", wireType) } - var byteLen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowMsg @@ -2170,25 +2170,23 @@ func (m *MsgInstantiateContract) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthMsg } - postIndex := iNdEx + byteLen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthMsg } if postIndex > l { return io.ErrUnexpectedEOF } - m.Admin = append(m.Admin[:0], dAtA[iNdEx:postIndex]...) - if m.Admin == nil { - m.Admin = []byte{} - } + m.Admin = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex From 3a48ff6f43285d3b4aa7d10d21ddde527ee7676e Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Mon, 12 Jun 2023 14:30:19 +0300 Subject: [PATCH 019/164] Rebuild protobufs --- .../shared/cosmos-proto/src/cosmwasm/msg.rs | 89 +++++----- proto/secret/compute/v1beta1/types.proto | 2 +- x/compute/internal/types/types.pb.go | 152 +++++++++--------- 3 files changed, 120 insertions(+), 123 deletions(-) diff --git a/cosmwasm/enclaves/shared/cosmos-proto/src/cosmwasm/msg.rs b/cosmwasm/enclaves/shared/cosmos-proto/src/cosmwasm/msg.rs index 92db95e57..f05fbe7ab 100644 --- a/cosmwasm/enclaves/shared/cosmos-proto/src/cosmwasm/msg.rs +++ b/cosmwasm/enclaves/shared/cosmos-proto/src/cosmwasm/msg.rs @@ -470,7 +470,7 @@ pub struct MsgInstantiateContract { pub init_msg: ::std::vec::Vec, pub init_funds: ::protobuf::RepeatedField, pub callback_sig: ::std::vec::Vec, - pub admin: ::std::vec::Vec, + pub admin: ::std::string::String, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -657,10 +657,10 @@ impl MsgInstantiateContract { ::std::mem::replace(&mut self.callback_sig, ::std::vec::Vec::new()) } - // bytes admin = 8; + // string admin = 8; - pub fn get_admin(&self) -> &[u8] { + pub fn get_admin(&self) -> &str { &self.admin } pub fn clear_admin(&mut self) { @@ -668,19 +668,19 @@ impl MsgInstantiateContract { } // Param is passed by value, moved - pub fn set_admin(&mut self, v: ::std::vec::Vec) { + pub fn set_admin(&mut self, v: ::std::string::String) { self.admin = v; } // Mutable pointer to the field. // If field is not initialized, it is initialized with default value first. - pub fn mut_admin(&mut self) -> &mut ::std::vec::Vec { + pub fn mut_admin(&mut self) -> &mut ::std::string::String { &mut self.admin } // Take field - pub fn take_admin(&mut self) -> ::std::vec::Vec { - ::std::mem::replace(&mut self.admin, ::std::vec::Vec::new()) + pub fn take_admin(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.admin, ::std::string::String::new()) } } @@ -724,7 +724,7 @@ impl ::protobuf::Message for MsgInstantiateContract { ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.callback_sig)?; }, 8 => { - ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.admin)?; + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.admin)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -761,7 +761,7 @@ impl ::protobuf::Message for MsgInstantiateContract { my_size += ::protobuf::rt::bytes_size(7, &self.callback_sig); } if !self.admin.is_empty() { - my_size += ::protobuf::rt::bytes_size(8, &self.admin); + my_size += ::protobuf::rt::string_size(8, &self.admin); } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -793,7 +793,7 @@ impl ::protobuf::Message for MsgInstantiateContract { os.write_bytes(7, &self.callback_sig)?; } if !self.admin.is_empty() { - os.write_bytes(8, &self.admin)?; + os.write_string(8, &self.admin)?; } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -868,7 +868,7 @@ impl ::protobuf::Message for MsgInstantiateContract { |m: &MsgInstantiateContract| { &m.callback_sig }, |m: &mut MsgInstantiateContract| { &mut m.callback_sig }, )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "admin", |m: &MsgInstantiateContract| { &m.admin }, |m: &mut MsgInstantiateContract| { &mut m.admin }, @@ -2771,7 +2771,7 @@ static file_descriptor_proto_data: &'static [u8] = b"\ SMByteCode\x12\x16\n\x06source\x18\x03\x20\x01(\tR\x06source\x12\x18\n\ \x07builder\x18\x04\x20\x01(\tR\x07builder:\x04\x88\xa0\x1f\0\";\n\x14Ms\ gStoreCodeResponse\x12#\n\x07code_id\x18\x01\x20\x01(\x04R\x06codeIdB\n\ - \xe2\xde\x1f\x06CodeID\"\xd6\x03\n\x16MsgInstantiateContract\x12I\n\x06s\ + \xe2\xde\x1f\x06CodeID\"\xa3\x03\n\x16MsgInstantiateContract\x12I\n\x06s\ ender\x18\x01\x20\x01(\x0cR\x06senderB1\xfa\xde\x1f-github.com/cosmos/co\ smos-sdk/types.AccAddress\x12,\n\x12callback_code_hash\x18\x02\x20\x01(\ \tR\x10callbackCodeHash\x12#\n\x07code_id\x18\x03\x20\x01(\x04R\x06codeI\ @@ -2780,39 +2780,38 @@ static file_descriptor_proto_data: &'static [u8] = b"\ unds\x18\x06\x20\x03(\x0b2\x19.cosmos.base.v1beta1.CoinR\tinitFundsB0\ \xaa\xdf\x1f(github.com/cosmos/cosmos-sdk/types.Coins\xc8\xde\x1f\0\x122\ \n\x0ccallback_sig\x18\x07\x20\x01(\x0cR\x0bcallbackSigB\x0f\xe2\xde\x1f\ - \x0bCallbackSig\x12G\n\x05admin\x18\x08\x20\x01(\x0cR\x05adminB1\xfa\xde\ - \x1f-github.com/cosmos/cosmos-sdk/types.AccAddress:\x04\x88\xa0\x1f\0\"N\ - \n\x1eMsgInstantiateContractResponse\x12\x18\n\x07address\x18\x01\x20\ - \x01(\tR\x07address\x12\x12\n\x04data\x18\x02\x20\x01(\x0cR\x04data\"\ - \x94\x03\n\x12MsgExecuteContract\x12I\n\x06sender\x18\x01\x20\x01(\x0cR\ - \x06senderB1\xfa\xde\x1f-github.com/cosmos/cosmos-sdk/types.AccAddress\ - \x12M\n\x08contract\x18\x02\x20\x01(\x0cR\x08contractB1\xfa\xde\x1f-gith\ - ub.com/cosmos/cosmos-sdk/types.AccAddress\x12\x10\n\x03msg\x18\x03\x20\ - \x01(\x0cR\x03msg\x12,\n\x12callback_code_hash\x18\x04\x20\x01(\tR\x10ca\ - llbackCodeHash\x12j\n\nsent_funds\x18\x05\x20\x03(\x0b2\x19.cosmos.base.\ - v1beta1.CoinR\tsentFundsB0\xaa\xdf\x1f(github.com/cosmos/cosmos-sdk/type\ - s.Coins\xc8\xde\x1f\0\x122\n\x0ccallback_sig\x18\x06\x20\x01(\x0cR\x0bca\ - llbackSigB\x0f\xe2\xde\x1f\x0bCallbackSig:\x04\x88\xa0\x1f\0\"0\n\x1aMsg\ - ExecuteContractResponse\x12\x12\n\x04data\x18\x01\x20\x01(\x0cR\x04data\ - \"\x7f\n\x12MsgMigrateContract\x12\x16\n\x06sender\x18\x01\x20\x01(\tR\ - \x06sender\x12\x1a\n\x08contract\x18\x02\x20\x01(\tR\x08contract\x12#\n\ - \x07code_id\x18\x03\x20\x01(\x04R\x06codeIdB\n\xe2\xde\x1f\x06CodeID\x12\ - \x10\n\x03msg\x18\x04\x20\x01(\x0cR\x03msg\"0\n\x1aMsgMigrateContractRes\ - ponse\x12\x12\n\x04data\x18\x01\x20\x01(\x0cR\x04data\"a\n\x0eMsgUpdateA\ - dmin\x12\x16\n\x06sender\x18\x01\x20\x01(\tR\x06sender\x12\x1b\n\tnew_ad\ - min\x18\x02\x20\x01(\tR\x08newAdmin\x12\x1a\n\x08contract\x18\x03\x20\ - \x01(\tR\x08contract\"\x18\n\x16MsgUpdateAdminResponse\"C\n\rMsgClearAdm\ - in\x12\x16\n\x06sender\x18\x01\x20\x01(\tR\x06sender\x12\x1a\n\x08contra\ - ct\x18\x03\x20\x01(\tR\x08contract\"\x17\n\x15MsgClearAdminResponse2\xcb\ - \x03\n\x03Msg\x12_\n\tStoreCode\x12$.secret.compute.v1beta1.MsgStoreCode\ - \x1a,.secret.compute.v1beta1.MsgStoreCodeResponse\x12}\n\x13InstantiateC\ - ontract\x12..secret.compute.v1beta1.MsgInstantiateContract\x1a6.secret.c\ - ompute.v1beta1.MsgInstantiateContractResponse\x12q\n\x0fExecuteContract\ - \x12*.secret.compute.v1beta1.MsgExecuteContract\x1a2.secret.compute.v1be\ - ta1.MsgExecuteContractResponse\x12q\n\x0fMigrateContract\x12*.secret.com\ - pute.v1beta1.MsgMigrateContract\x1a2.secret.compute.v1beta1.MsgMigrateCo\ - ntractResponseB = ::protobuf::rt::LazyV2::INIT; diff --git a/proto/secret/compute/v1beta1/types.proto b/proto/secret/compute/v1beta1/types.proto index 5737bca7b..07036b8fa 100644 --- a/proto/secret/compute/v1beta1/types.proto +++ b/proto/secret/compute/v1beta1/types.proto @@ -56,7 +56,7 @@ message ContractInfo { AbsoluteTxPosition created = 5; string ibc_port_id = 6 [ (gogoproto.customname) = "IBCPortID" ]; // Admin is an optional address that can execute migrations - bytes admin = 7 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"]; + string admin = 7; // Proof that enclave executed the instantiate command bytes admin_proof = 8; } diff --git a/x/compute/internal/types/types.pb.go b/x/compute/internal/types/types.pb.go index 1f522fa20..16464e4e3 100644 --- a/x/compute/internal/types/types.pb.go +++ b/x/compute/internal/types/types.pb.go @@ -293,7 +293,7 @@ type ContractInfo struct { Created *AbsoluteTxPosition `protobuf:"bytes,5,opt,name=created,proto3" json:"created,omitempty"` IBCPortID string `protobuf:"bytes,6,opt,name=ibc_port_id,json=ibcPortId,proto3" json:"ibc_port_id,omitempty"` // Admin is an optional address that can execute migrations - Admin github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,7,opt,name=admin,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"admin,omitempty"` + Admin string `protobuf:"bytes,7,opt,name=admin,proto3" json:"admin,omitempty"` // Proof that enclave executed the instantiate command AdminProof []byte `protobuf:"bytes,8,opt,name=admin_proof,json=adminProof,proto3" json:"admin_proof,omitempty"` } @@ -475,73 +475,73 @@ func init() { } var fileDescriptor_8ba7f40a6d1951b3 = []byte{ - // 1047 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xcb, 0x6e, 0x23, 0x45, - 0x17, 0x76, 0xc7, 0xf7, 0xb2, 0xff, 0xf9, 0xad, 0x22, 0x0c, 0x1e, 0x23, 0xd9, 0xa6, 0x41, 0x10, - 0x92, 0x89, 0x4d, 0x06, 0x16, 0xa3, 0x2c, 0x90, 0x7c, 0xe9, 0x49, 0x7a, 0x42, 0x6c, 0xab, 0xec, - 0x64, 0x14, 0x2e, 0x6a, 0xf5, 0xa5, 0x62, 0x97, 0xd2, 0xee, 0xb2, 0xba, 0xca, 0xc1, 0x7e, 0x03, - 0xe4, 0x15, 0x4b, 0x36, 0x96, 0x90, 0x40, 0xa3, 0x79, 0x01, 0xde, 0x61, 0x96, 0xb3, 0x64, 0x65, - 0x81, 0xf3, 0x00, 0x48, 0x48, 0x6c, 0x66, 0x85, 0xba, 0xba, 0x7d, 0x11, 0x24, 0x4a, 0x40, 0xac, - 0xfa, 0x9c, 0xaa, 0x73, 0xbe, 0x53, 0xe7, 0x3b, 0x5f, 0x95, 0x1a, 0xc8, 0x0c, 0x9b, 0x2e, 0xe6, - 0x65, 0x93, 0xf6, 0x07, 0x43, 0x8e, 0xcb, 0x97, 0x7b, 0x06, 0xe6, 0xfa, 0x5e, 0x99, 0x8f, 0x07, - 0x98, 0x95, 0x06, 0x2e, 0xe5, 0x14, 0xde, 0xf7, 0x63, 0x4a, 0x41, 0x4c, 0x29, 0x88, 0xc9, 0x6d, - 0x76, 0x69, 0x97, 0x8a, 0x90, 0xb2, 0x67, 0xf9, 0xd1, 0xb2, 0x09, 0xfe, 0x5f, 0x31, 0x4d, 0xcc, - 0x58, 0x67, 0x3c, 0xc0, 0x2d, 0xdd, 0xd5, 0xfb, 0xf0, 0x29, 0x88, 0x5e, 0xea, 0xf6, 0x10, 0x67, - 0xa5, 0xa2, 0xb4, 0x75, 0xef, 0x91, 0x5c, 0xba, 0x1e, 0xb0, 0xb4, 0xca, 0xab, 0x66, 0x7e, 0x9f, - 0x15, 0xd2, 0x63, 0xbd, 0x6f, 0xef, 0xcb, 0x22, 0x55, 0x46, 0x3e, 0xc4, 0x7e, 0xe4, 0xbb, 0xef, - 0x0b, 0x92, 0xfc, 0x5c, 0x02, 0x89, 0x1a, 0xb5, 0xb0, 0xea, 0x9c, 0x53, 0xf8, 0x36, 0x48, 0x9a, - 0xd4, 0xc2, 0x5a, 0x4f, 0x67, 0x3d, 0x51, 0x22, 0x8d, 0x12, 0xde, 0xc2, 0xa1, 0xce, 0x7a, 0xf0, - 0x08, 0xc4, 0x4d, 0x17, 0xeb, 0x9c, 0xba, 0xd9, 0x0d, 0x6f, 0xab, 0xba, 0xf7, 0x7a, 0x56, 0xd8, - 0xed, 0x12, 0xde, 0x1b, 0x1a, 0xde, 0x01, 0xca, 0x26, 0x65, 0x7d, 0xca, 0x82, 0xcf, 0x2e, 0xb3, - 0x2e, 0x82, 0xde, 0x2b, 0xa6, 0x59, 0xb1, 0x2c, 0x17, 0x33, 0x86, 0x16, 0x08, 0xf0, 0x3e, 0x88, - 0x31, 0x3a, 0x74, 0x4d, 0x9c, 0x0d, 0x17, 0xa5, 0xad, 0x24, 0x0a, 0x3c, 0x98, 0x05, 0x71, 0x63, - 0x48, 0x6c, 0x0b, 0xbb, 0xd9, 0x88, 0xd8, 0x58, 0xb8, 0xf2, 0x17, 0x00, 0xd6, 0xa8, 0xc3, 0x5d, - 0xdd, 0xe4, 0xb5, 0x21, 0xe3, 0xb4, 0x2f, 0x4e, 0x5c, 0x06, 0x29, 0xec, 0x98, 0xb6, 0x7e, 0x89, - 0xb5, 0x0b, 0x3c, 0xf6, 0xcf, 0x5c, 0xbd, 0x37, 0x9f, 0x15, 0x80, 0xe2, 0x2f, 0x1f, 0xe1, 0x31, - 0x02, 0x78, 0x69, 0xc3, 0x4d, 0x10, 0xb5, 0x75, 0x03, 0xdb, 0xa2, 0x87, 0x24, 0xf2, 0x1d, 0x99, - 0x80, 0xd4, 0x02, 0xdc, 0x0b, 0xca, 0x80, 0xf0, 0x12, 0x0d, 0x79, 0x26, 0x3c, 0x04, 0x09, 0xea, - 0x92, 0x2e, 0x71, 0x74, 0x3f, 0x33, 0xf5, 0xe8, 0xe1, 0x4d, 0xdc, 0xaf, 0x01, 0x3d, 0x23, 0xbc, - 0xd7, 0x72, 0x29, 0x3d, 0x47, 0xcb, 0x6c, 0xf9, 0x53, 0xb0, 0x79, 0x5d, 0xc4, 0x35, 0x35, 0x37, - 0x41, 0x74, 0xe0, 0x6d, 0xf9, 0x74, 0x23, 0xdf, 0x91, 0xff, 0xd8, 0x00, 0xe9, 0x05, 0x80, 0xa0, - 0xe0, 0x5d, 0x10, 0x17, 0x43, 0x23, 0x96, 0x48, 0x8e, 0x54, 0xc1, 0x7c, 0x56, 0x88, 0x89, 0x99, - 0xd6, 0x51, 0xcc, 0xdb, 0x52, 0xad, 0xff, 0x76, 0x78, 0x4b, 0x0e, 0x23, 0x6b, 0x1c, 0xc2, 0x7a, - 0x50, 0x02, 0x5b, 0xd9, 0xa8, 0x60, 0x68, 0xfb, 0x46, 0x75, 0x1a, 0x8c, 0xda, 0x43, 0x8e, 0x3b, - 0xa3, 0x16, 0x65, 0x84, 0x13, 0xea, 0xa0, 0x45, 0x2a, 0xdc, 0x05, 0x29, 0x62, 0x98, 0xda, 0x80, - 0xba, 0xdc, 0xeb, 0x28, 0xe6, 0x55, 0xa8, 0xfe, 0x6f, 0x3e, 0x2b, 0x24, 0xd5, 0x6a, 0xad, 0x45, - 0x5d, 0xae, 0xd6, 0x51, 0x92, 0x18, 0xa6, 0x30, 0x2d, 0x78, 0x00, 0xa2, 0xba, 0xd5, 0x27, 0x4e, - 0x36, 0xfe, 0x6f, 0xbb, 0xf2, 0xf3, 0x61, 0x01, 0xa4, 0x84, 0xa1, 0xf9, 0x94, 0x27, 0x04, 0xe5, - 0x40, 0x2c, 0x89, 0xf9, 0xc8, 0x08, 0xc0, 0xbf, 0x9f, 0x1b, 0xbe, 0x03, 0xd2, 0x86, 0x4d, 0xcd, - 0x0b, 0xad, 0x87, 0x49, 0xb7, 0xc7, 0xc5, 0x04, 0xc2, 0x28, 0x25, 0xd6, 0x0e, 0xc5, 0x12, 0x7c, - 0x00, 0x12, 0x7c, 0xa4, 0x11, 0xc7, 0xc2, 0x23, 0xc1, 0x7d, 0x04, 0xc5, 0xf9, 0x48, 0xf5, 0x5c, - 0x99, 0x80, 0xe8, 0x31, 0xb5, 0xb0, 0x0d, 0x9f, 0x82, 0xf0, 0xd1, 0x52, 0xbe, 0x8f, 0x5f, 0xcf, - 0x0a, 0x9f, 0xac, 0x35, 0xc1, 0xb1, 0x63, 0x61, 0xb7, 0x4f, 0x1c, 0xbe, 0x6e, 0xda, 0xc4, 0x60, - 0x65, 0x63, 0xcc, 0x31, 0x2b, 0x1d, 0xe2, 0x51, 0xd5, 0x33, 0x50, 0x38, 0x50, 0xf8, 0xa9, 0x78, - 0x23, 0x02, 0xd9, 0x08, 0x47, 0xfe, 0x4d, 0x02, 0xd9, 0xe5, 0xfd, 0xf1, 0xae, 0x34, 0x61, 0x9c, - 0xba, 0x63, 0xc5, 0xe1, 0xee, 0x18, 0x9e, 0x82, 0x24, 0x1d, 0x60, 0x57, 0xf7, 0x5a, 0x0a, 0x9e, - 0x96, 0xc7, 0xb7, 0xc9, 0x7b, 0x0d, 0xa4, 0xb9, 0xc8, 0xf5, 0x1e, 0x1c, 0xb4, 0x82, 0x5a, 0x97, - 0xe6, 0xc6, 0x8d, 0xd2, 0xac, 0x83, 0xf8, 0x70, 0x60, 0x09, 0xdd, 0x84, 0xff, 0xb9, 0x6e, 0x82, - 0x54, 0xef, 0xfa, 0xf4, 0x59, 0x57, 0x28, 0x32, 0x8d, 0x3c, 0x73, 0xfb, 0x27, 0x09, 0x80, 0xd5, - 0x3b, 0x08, 0xdf, 0x07, 0xc9, 0x93, 0x46, 0x5d, 0x79, 0xa2, 0x36, 0x94, 0x7a, 0x26, 0x94, 0x7b, - 0x6b, 0x32, 0x2d, 0xbe, 0xb1, 0xda, 0x3e, 0x71, 0x2c, 0x7c, 0x4e, 0x1c, 0x6c, 0xc1, 0x22, 0x88, - 0x35, 0x9a, 0xd5, 0x66, 0xfd, 0x2c, 0x23, 0xe5, 0x36, 0x27, 0xd3, 0x62, 0x66, 0x15, 0xd4, 0xa0, - 0x06, 0xb5, 0xc6, 0x70, 0x07, 0xa4, 0x9b, 0x8d, 0xcf, 0xce, 0xb4, 0x4a, 0xbd, 0x8e, 0x94, 0x76, - 0x3b, 0xb3, 0x91, 0x7b, 0x30, 0x99, 0x16, 0xdf, 0x5c, 0xc5, 0x35, 0x1d, 0x7b, 0x1c, 0xc8, 0xcb, - 0x2b, 0xab, 0x9c, 0x2a, 0xe8, 0x4c, 0x20, 0x86, 0xff, 0x5a, 0x56, 0xb9, 0xc4, 0xee, 0xd8, 0x03, - 0xcd, 0x25, 0xbe, 0xf9, 0x21, 0x1f, 0x7a, 0xf1, 0x63, 0x3e, 0xb4, 0xfd, 0x3c, 0x0c, 0x8a, 0xb7, - 0x91, 0x0c, 0x31, 0xf8, 0xa8, 0xd6, 0x6c, 0x74, 0x50, 0xa5, 0xd6, 0xd1, 0x6a, 0xcd, 0xba, 0xa2, - 0x1d, 0xaa, 0xed, 0x4e, 0x13, 0x9d, 0x69, 0xcd, 0x96, 0x82, 0x2a, 0x1d, 0xb5, 0xd9, 0xd0, 0x3a, - 0x67, 0x2d, 0x45, 0x3b, 0x69, 0xb4, 0x5b, 0x4a, 0x4d, 0x7d, 0xa2, 0x8a, 0xa6, 0xcb, 0x93, 0x69, - 0x71, 0xe7, 0x36, 0xec, 0x13, 0x87, 0x0d, 0xb0, 0x49, 0xce, 0x09, 0xb6, 0xe0, 0x33, 0xf0, 0xe1, - 0x9d, 0xca, 0xa8, 0x0d, 0xb5, 0x93, 0x91, 0x72, 0x5b, 0x93, 0x69, 0xf1, 0xbd, 0xdb, 0xf0, 0x55, - 0x87, 0x70, 0xf8, 0x15, 0x78, 0x78, 0x27, 0xe0, 0x63, 0xf5, 0x00, 0x55, 0x3a, 0x4a, 0x66, 0x23, - 0xb7, 0x33, 0x99, 0x16, 0x3f, 0xb8, 0x0d, 0xfb, 0x98, 0x74, 0x5d, 0x9d, 0xe3, 0x3b, 0xc3, 0x1f, - 0x28, 0x0d, 0xa5, 0xad, 0xb6, 0x33, 0xe1, 0xbb, 0xc1, 0x1f, 0x60, 0x07, 0x33, 0xc2, 0x72, 0x11, - 0x6f, 0x58, 0xd5, 0x2f, 0x5f, 0xfe, 0x9a, 0x0f, 0xbd, 0x98, 0xe7, 0xa5, 0x97, 0xf3, 0xbc, 0xf4, - 0x6a, 0x9e, 0x97, 0x7e, 0x99, 0xe7, 0xa5, 0x6f, 0xaf, 0xf2, 0xa1, 0x57, 0x57, 0xf9, 0xd0, 0xcf, - 0x57, 0xf9, 0xd0, 0xe7, 0xfb, 0x6b, 0xb7, 0x98, 0x99, 0x2e, 0xb7, 0x75, 0x83, 0x95, 0xdb, 0x42, - 0xdc, 0x0d, 0xcc, 0xbf, 0xa6, 0xee, 0x45, 0x79, 0xb4, 0xfc, 0x61, 0x20, 0x0e, 0xc7, 0xae, 0xa3, - 0xdb, 0xfe, 0x13, 0x65, 0xc4, 0xc4, 0x4f, 0xc0, 0xc7, 0x7f, 0x06, 0x00, 0x00, 0xff, 0xff, 0x7b, - 0x22, 0x8a, 0xe1, 0x58, 0x08, 0x00, 0x00, + // 1043 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0x4b, 0x6f, 0x23, 0x45, + 0x10, 0xf6, 0xc4, 0x8e, 0x1f, 0x6d, 0xb3, 0x58, 0x4d, 0x58, 0xbc, 0x46, 0xb2, 0xcd, 0x80, 0x60, + 0xd9, 0x6c, 0x6c, 0xb2, 0x70, 0x58, 0xe5, 0x80, 0xe4, 0xc7, 0x6c, 0x32, 0x1b, 0x62, 0x5b, 0x6d, + 0x27, 0xab, 0xf0, 0xd0, 0x68, 0x1e, 0x1d, 0xbb, 0x95, 0xf1, 0xb4, 0xd5, 0xdd, 0x0e, 0xf6, 0x3f, + 0x40, 0x3e, 0x71, 0xe4, 0x62, 0x09, 0x09, 0xb4, 0xda, 0x3f, 0xc0, 0x1f, 0xe0, 0xb4, 0xc7, 0x3d, + 0x72, 0xb2, 0xc0, 0xf9, 0x01, 0x48, 0x1c, 0xf7, 0x84, 0xa6, 0xc7, 0x2f, 0x41, 0xa2, 0x04, 0x89, + 0xd3, 0x54, 0x75, 0x57, 0x7d, 0x55, 0xfd, 0xf5, 0x57, 0x3d, 0x40, 0xe5, 0xd8, 0x66, 0x58, 0x94, + 0x6c, 0xda, 0xeb, 0x0f, 0x04, 0x2e, 0x5d, 0xec, 0x5a, 0x58, 0x98, 0xbb, 0x25, 0x31, 0xea, 0x63, + 0x5e, 0xec, 0x33, 0x2a, 0x28, 0xbc, 0x1b, 0xc4, 0x14, 0xe7, 0x31, 0xc5, 0x79, 0x4c, 0x76, 0xab, + 0x43, 0x3b, 0x54, 0x86, 0x94, 0x7c, 0x2b, 0x88, 0x56, 0x6d, 0xf0, 0x66, 0xd9, 0xb6, 0x31, 0xe7, + 0xed, 0x51, 0x1f, 0x37, 0x4d, 0x66, 0xf6, 0xe0, 0x53, 0xb0, 0x79, 0x61, 0xba, 0x03, 0x9c, 0x51, + 0x0a, 0xca, 0xfd, 0x3b, 0x8f, 0xd4, 0xe2, 0xd5, 0x80, 0xc5, 0x55, 0x5e, 0x25, 0xfd, 0xd7, 0x34, + 0x9f, 0x1a, 0x99, 0x3d, 0x77, 0x4f, 0x95, 0xa9, 0x2a, 0x0a, 0x20, 0xf6, 0x22, 0x3f, 0xfc, 0x98, + 0x57, 0xd4, 0xe7, 0x0a, 0x88, 0x57, 0xa9, 0x83, 0x75, 0xef, 0x8c, 0xc2, 0x77, 0x41, 0xc2, 0xa6, + 0x0e, 0x36, 0xba, 0x26, 0xef, 0xca, 0x12, 0x29, 0x14, 0xf7, 0x17, 0x0e, 0x4c, 0xde, 0x85, 0x87, + 0x20, 0x66, 0x33, 0x6c, 0x0a, 0xca, 0x32, 0x1b, 0xfe, 0x56, 0x65, 0xf7, 0xf5, 0x34, 0xbf, 0xd3, + 0x21, 0xa2, 0x3b, 0xb0, 0xfc, 0x06, 0x4a, 0x36, 0xe5, 0x3d, 0xca, 0xe7, 0x9f, 0x1d, 0xee, 0x9c, + 0xcf, 0xcf, 0x5e, 0xb6, 0xed, 0xb2, 0xe3, 0x30, 0xcc, 0x39, 0x5a, 0x20, 0xc0, 0xbb, 0x20, 0xca, + 0xe9, 0x80, 0xd9, 0x38, 0x13, 0x2e, 0x28, 0xf7, 0x13, 0x68, 0xee, 0xc1, 0x0c, 0x88, 0x59, 0x03, + 0xe2, 0x3a, 0x98, 0x65, 0x22, 0x72, 0x63, 0xe1, 0xaa, 0x5f, 0x01, 0x58, 0xa5, 0x9e, 0x60, 0xa6, + 0x2d, 0xaa, 0x03, 0x2e, 0x68, 0x4f, 0x76, 0x5c, 0x02, 0x49, 0xec, 0xd9, 0xae, 0x79, 0x81, 0x8d, + 0x73, 0x3c, 0x0a, 0x7a, 0xae, 0xdc, 0x99, 0x4d, 0xf3, 0x40, 0x0b, 0x96, 0x0f, 0xf1, 0x08, 0x01, + 0xbc, 0xb4, 0xe1, 0x16, 0xd8, 0x74, 0x4d, 0x0b, 0xbb, 0xf2, 0x0c, 0x09, 0x14, 0x38, 0x2a, 0x01, + 0xc9, 0x05, 0xb8, 0x1f, 0x94, 0x06, 0xe1, 0x25, 0x1a, 0xf2, 0x4d, 0x78, 0x00, 0xe2, 0x94, 0x91, + 0x0e, 0xf1, 0xcc, 0x20, 0x33, 0xf9, 0xe8, 0xe1, 0x75, 0xdc, 0xaf, 0x01, 0x3d, 0x23, 0xa2, 0xdb, + 0x64, 0x94, 0x9e, 0xa1, 0x65, 0xb6, 0xfa, 0x39, 0xd8, 0xba, 0x2a, 0xe2, 0x8a, 0x9a, 0x5b, 0x60, + 0xb3, 0xef, 0x6f, 0x05, 0x74, 0xa3, 0xc0, 0x51, 0x7f, 0xdd, 0x00, 0xa9, 0x05, 0x80, 0xa4, 0xe0, + 0x7d, 0x10, 0x93, 0x97, 0x46, 0x1c, 0x99, 0x1c, 0xa9, 0x80, 0xd9, 0x34, 0x1f, 0x95, 0x77, 0x5a, + 0x43, 0x51, 0x7f, 0x4b, 0x77, 0xfe, 0xdf, 0xcb, 0x5b, 0x72, 0x18, 0x59, 0xe3, 0x10, 0xd6, 0xe6, + 0x25, 0xb0, 0x93, 0xd9, 0x94, 0x0c, 0x3d, 0xb8, 0x56, 0x9d, 0x16, 0xa7, 0xee, 0x40, 0xe0, 0xf6, + 0xb0, 0x49, 0x39, 0x11, 0x84, 0x7a, 0x68, 0x91, 0x0a, 0x77, 0x40, 0x92, 0x58, 0xb6, 0xd1, 0xa7, + 0x4c, 0xf8, 0x27, 0x8a, 0xfa, 0x15, 0x2a, 0x6f, 0xcc, 0xa6, 0xf9, 0x84, 0x5e, 0xa9, 0x36, 0x29, + 0x13, 0x7a, 0x0d, 0x25, 0x88, 0x65, 0x4b, 0xd3, 0xf1, 0x5b, 0x31, 0x9d, 0x1e, 0xf1, 0x32, 0xb1, + 0xa0, 0x15, 0xe9, 0xc0, 0x3c, 0x48, 0x4a, 0xc3, 0x08, 0xf8, 0x8b, 0x4b, 0xfe, 0x80, 0x5c, 0x92, + 0x64, 0xab, 0x08, 0xc0, 0x7f, 0x37, 0x01, 0xdf, 0x03, 0x29, 0xcb, 0xa5, 0xf6, 0xb9, 0xd1, 0xc5, + 0xa4, 0xd3, 0x15, 0x92, 0xce, 0x30, 0x4a, 0xca, 0xb5, 0x03, 0xb9, 0x04, 0xef, 0x81, 0xb8, 0x18, + 0x1a, 0xc4, 0x73, 0xf0, 0x50, 0x12, 0x19, 0x41, 0x31, 0x31, 0xd4, 0x7d, 0x57, 0x25, 0x60, 0xf3, + 0x88, 0x3a, 0xd8, 0x85, 0x4f, 0x41, 0xf8, 0x70, 0xa9, 0xc5, 0xc7, 0xaf, 0xa7, 0xf9, 0xcf, 0xd6, + 0x78, 0x16, 0xd8, 0x73, 0x30, 0xeb, 0x11, 0x4f, 0xac, 0x9b, 0x2e, 0xb1, 0x78, 0xc9, 0x1a, 0x09, + 0xcc, 0x8b, 0x07, 0x78, 0x58, 0xf1, 0x0d, 0x14, 0x9e, 0xcb, 0xf5, 0x44, 0x0e, 0xfc, 0x5c, 0x03, + 0xd2, 0x51, 0xff, 0x54, 0x40, 0x66, 0x39, 0x0c, 0xfe, 0x7c, 0x12, 0x2e, 0x28, 0x1b, 0x69, 0x9e, + 0x60, 0x23, 0x78, 0x02, 0x12, 0xb4, 0x8f, 0x99, 0xe9, 0x1f, 0x69, 0xfe, 0x4e, 0x3c, 0xbe, 0x49, + 0xab, 0x6b, 0x20, 0x8d, 0x45, 0xae, 0xff, 0x7a, 0xa0, 0x15, 0xd4, 0xba, 0xce, 0x36, 0xae, 0xd5, + 0x59, 0x0d, 0xc4, 0x06, 0x7d, 0x47, 0x8a, 0x20, 0xfc, 0xdf, 0x45, 0x30, 0x4f, 0xf5, 0x67, 0xa1, + 0xc7, 0x3b, 0x52, 0x5e, 0x29, 0xe4, 0x9b, 0x0f, 0x7e, 0x51, 0x00, 0x58, 0x3d, 0x6a, 0xf0, 0x43, + 0x90, 0x38, 0xae, 0xd7, 0xb4, 0x27, 0x7a, 0x5d, 0xab, 0xa5, 0x43, 0xd9, 0x77, 0xc6, 0x93, 0xc2, + 0x5b, 0xab, 0xed, 0x63, 0xcf, 0xc1, 0x67, 0xc4, 0xc3, 0x0e, 0x2c, 0x80, 0x68, 0xbd, 0x51, 0x69, + 0xd4, 0x4e, 0xd3, 0x4a, 0x76, 0x6b, 0x3c, 0x29, 0xa4, 0x57, 0x41, 0x75, 0x6a, 0x51, 0x67, 0x04, + 0xb7, 0x41, 0xaa, 0x51, 0xff, 0xe2, 0xd4, 0x28, 0xd7, 0x6a, 0x48, 0x6b, 0xb5, 0xd2, 0x1b, 0xd9, + 0x7b, 0xe3, 0x49, 0xe1, 0xed, 0x55, 0x5c, 0xc3, 0x73, 0x47, 0xf3, 0x09, 0xf0, 0xcb, 0x6a, 0x27, + 0x1a, 0x3a, 0x95, 0x88, 0xe1, 0x7f, 0x96, 0xd5, 0x2e, 0x30, 0x1b, 0xf9, 0xa0, 0xd9, 0xf8, 0x77, + 0x3f, 0xe5, 0x42, 0x2f, 0x7e, 0xce, 0x85, 0x1e, 0x3c, 0x0f, 0x83, 0xc2, 0x4d, 0x24, 0x43, 0x0c, + 0x3e, 0xa9, 0x36, 0xea, 0x6d, 0x54, 0xae, 0xb6, 0x8d, 0x6a, 0xa3, 0xa6, 0x19, 0x07, 0x7a, 0xab, + 0xdd, 0x40, 0xa7, 0x46, 0xa3, 0xa9, 0xa1, 0x72, 0x5b, 0x6f, 0xd4, 0x8d, 0xf6, 0x69, 0x53, 0x33, + 0x8e, 0xeb, 0xad, 0xa6, 0x56, 0xd5, 0x9f, 0xe8, 0xf2, 0xd0, 0xa5, 0xf1, 0xa4, 0xb0, 0x7d, 0x13, + 0xf6, 0xb1, 0xc7, 0xfb, 0xd8, 0x26, 0x67, 0x04, 0x3b, 0xf0, 0x19, 0xf8, 0xf8, 0x56, 0x65, 0xf4, + 0xba, 0xde, 0x4e, 0x2b, 0xd9, 0xfb, 0xe3, 0x49, 0xe1, 0x83, 0x9b, 0xf0, 0x75, 0x8f, 0x08, 0xf8, + 0x0d, 0x78, 0x78, 0x2b, 0xe0, 0x23, 0x7d, 0x1f, 0x95, 0xdb, 0x5a, 0x7a, 0x23, 0xbb, 0x3d, 0x9e, + 0x14, 0x3e, 0xba, 0x09, 0xfb, 0x88, 0x74, 0x98, 0x29, 0xf0, 0xad, 0xe1, 0xf7, 0xb5, 0xba, 0xd6, + 0xd2, 0x5b, 0xe9, 0xf0, 0xed, 0xe0, 0xf7, 0xb1, 0x87, 0x39, 0xe1, 0xd9, 0x88, 0x7f, 0x59, 0x95, + 0xaf, 0x5f, 0xfe, 0x91, 0x0b, 0xbd, 0x98, 0xe5, 0x94, 0x97, 0xb3, 0x9c, 0xf2, 0x6a, 0x96, 0x53, + 0x7e, 0x9f, 0xe5, 0x94, 0xef, 0x2f, 0x73, 0xa1, 0x57, 0x97, 0xb9, 0xd0, 0x6f, 0x97, 0xb9, 0xd0, + 0x97, 0x7b, 0x6b, 0x53, 0xcc, 0x6d, 0x26, 0x5c, 0xd3, 0xe2, 0xa5, 0x96, 0x14, 0x77, 0x1d, 0x8b, + 0x6f, 0x29, 0x3b, 0x2f, 0x0d, 0x97, 0x7f, 0x7f, 0xe2, 0x09, 0xcc, 0x3c, 0xd3, 0x0d, 0x5e, 0x51, + 0x2b, 0x2a, 0xff, 0xe8, 0x9f, 0xfe, 0x1d, 0x00, 0x00, 0xff, 0xff, 0xf8, 0x2c, 0xb1, 0x67, 0x25, + 0x08, 0x00, 0x00, } func (this *AccessTypeParam) Equal(that interface{}) bool { @@ -716,7 +716,7 @@ func (this *ContractInfo) Equal(that interface{}) bool { if this.IBCPortID != that1.IBCPortID { return false } - if !bytes.Equal(this.Admin, that1.Admin) { + if this.Admin != that1.Admin { return false } if !bytes.Equal(this.AdminProof, that1.AdminProof) { @@ -2190,7 +2190,7 @@ func (m *ContractInfo) Unmarshal(dAtA []byte) error { if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Admin", wireType) } - var byteLen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -2200,25 +2200,23 @@ func (m *ContractInfo) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthTypes } - postIndex := iNdEx + byteLen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthTypes } if postIndex > l { return io.ErrUnexpectedEOF } - m.Admin = append(m.Admin[:0], dAtA[iNdEx:postIndex]...) - if m.Admin == nil { - m.Admin = []byte{} - } + m.Admin = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 8: if wireType != 2 { From 08502da0b8a1b89ce8d3aceccf0b0bba9a8cee30 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Mon, 12 Jun 2023 15:12:46 +0300 Subject: [PATCH 020/164] Update enclave types for string init admin --- cosmwasm/enclaves/shared/cosmos-types/src/types.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs index ee7865c37..531da2a45 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs @@ -310,6 +310,7 @@ pub enum StdCosmWasmMsg { init_funds: Vec, label: String, callback_sig: Option>, + admin: HumanAddr, }, Migrate { sender: HumanAddr, @@ -390,6 +391,7 @@ impl StdCosmWasmMsg { label, callback_sig, code_id: _, + admin, } => { let sender = CanonicalAddr::from_human(&sender).map_err(|err| { warn!("failed to turn human addr to canonical addr when parsing CosmWasmMsg: {:?}", err); @@ -409,6 +411,7 @@ impl StdCosmWasmMsg { init_funds, label, callback_sig, + admin, }) } Self::Other => Ok(CosmosSdkMsg::Other), @@ -584,6 +587,7 @@ pub enum CosmosSdkMsg { init_funds: Vec, label: String, callback_sig: Option>, + admin: HumanAddr, }, MsgMigrateContract { sender: CanonicalAddr, @@ -803,6 +807,7 @@ impl CosmosSdkMsg { init_funds, label: raw_msg.label, callback_sig, + admin: HumanAddr(raw_msg.admin), }) } From 614cb13227833af631b0d996860be2fc3e49ec17 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 13 Jun 2023 11:33:40 +0300 Subject: [PATCH 021/164] Fix Amino MsgMigrateContract inside the enclave --- cosmwasm/enclaves/shared/cosmos-types/src/types.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs index 531da2a45..64bb5b147 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs @@ -315,7 +315,7 @@ pub enum StdCosmWasmMsg { Migrate { sender: HumanAddr, contract: HumanAddr, - code_id: u64, + code_id: String, msg: String, }, // The core IBC messages don't support Amino From 869095fbdaa6fb1ad07c32ba501ab3ed3c3c582f Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 13 Jun 2023 11:35:32 +0300 Subject: [PATCH 022/164] Rename Amino & Direct sturcts inside the enclave --- .../enclaves/shared/cosmos-types/src/types.rs | 62 +++++++++---------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs index 64bb5b147..1c6f9203e 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs @@ -220,7 +220,7 @@ pub struct StdSignDoc { pub account_number: String, pub chain_id: String, pub memo: String, - pub msgs: Vec, + pub msgs: Vec, pub sequence: String, } @@ -257,7 +257,7 @@ impl SignDoc { #[derive(Debug)] pub struct TxBody { - pub messages: Vec, + pub messages: Vec, // Leaving this here for discoverability. We can use this, but don't verify it today. #[allow(dead_code)] memo: (), @@ -279,7 +279,7 @@ impl TxBody { let messages = tx_body .messages .into_iter() - .map(|any| CosmosSdkMsg::from_bytes(&any.value, handle_type)) + .map(|any| DirectCosmosMsg::from_bytes(&any.value, handle_type)) .collect::, _>>()?; Ok(TxBody { @@ -292,7 +292,7 @@ impl TxBody { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] #[serde(rename_all = "snake_case", tag = "type", content = "value")] -pub enum StdCosmWasmMsg { +pub enum AminoJsonCosmosMsg { #[serde(alias = "wasm/MsgExecuteContract")] Execute { sender: HumanAddr, @@ -312,6 +312,7 @@ pub enum StdCosmWasmMsg { callback_sig: Option>, admin: HumanAddr, }, + #[serde(alias = "wasm/MsgMigrateContract")] Migrate { sender: HumanAddr, contract: HumanAddr, @@ -329,8 +330,8 @@ pub fn deserialize_ignore_any<'de, D: serde::Deserializer<'de>, T: Default>( serde::de::IgnoredAny::deserialize(deserializer).map(|_| T::default()) } -impl StdCosmWasmMsg { - pub fn into_cosmwasm_msg(self) -> Result { +impl AminoJsonCosmosMsg { + pub fn into_cosmwasm_msg(self) -> Result { match self { Self::Migrate { sender, @@ -350,10 +351,9 @@ impl StdCosmWasmMsg { EnclaveError::FailedToDeserialize })?; let msg = msg.0; - Ok(CosmosSdkMsg::MsgMigrateContract { + Ok(DirectCosmosMsg::MsgMigrateContract { sender, msg, - code_id, contract, }) } @@ -376,7 +376,7 @@ impl StdCosmWasmMsg { EnclaveError::FailedToDeserialize })?; let msg = msg.0; - Ok(CosmosSdkMsg::MsgExecuteContract { + Ok(DirectCosmosMsg::MsgExecuteContract { sender, contract, msg, @@ -405,7 +405,7 @@ impl StdCosmWasmMsg { EnclaveError::FailedToDeserialize })?; let init_msg = init_msg.0; - Ok(CosmosSdkMsg::MsgInstantiateContract { + Ok(DirectCosmosMsg::MsgInstantiateContract { sender, init_msg, init_funds, @@ -414,7 +414,7 @@ impl StdCosmWasmMsg { admin, }) } - Self::Other => Ok(CosmosSdkMsg::Other), + Self::Other => Ok(DirectCosmosMsg::Other), } } } @@ -572,7 +572,7 @@ pub struct Packet { } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -pub enum CosmosSdkMsg { +pub enum DirectCosmosMsg { // CosmWasm: MsgExecuteContract { sender: CanonicalAddr, @@ -592,7 +592,6 @@ pub enum CosmosSdkMsg { MsgMigrateContract { sender: CanonicalAddr, contract: HumanAddr, - code_id: u64, msg: Vec, }, // IBC: @@ -626,7 +625,7 @@ pub enum CosmosSdkMsg { Other, } -impl CosmosSdkMsg { +impl DirectCosmosMsg { pub fn from_bytes(bytes: &[u8], handle_type: HandleType) -> Result { // Assaf: This function needs a refactor, as some protobufs are // compatible, e.g. try_parse_execute succeeds in parsing MsgRecvPacket as @@ -636,10 +635,10 @@ impl CosmosSdkMsg { HandleType::HANDLE_TYPE_EXECUTE => Self::try_parse_execute(bytes) .or_else(|_| Self::try_parse_instantiate(bytes)) .or_else(|_| Self::try_parse_migrate(bytes)), - HandleType::HANDLE_TYPE_REPLY => Ok(CosmosSdkMsg::Other), - HandleType::HANDLE_TYPE_IBC_CHANNEL_OPEN => Ok(CosmosSdkMsg::Other), - HandleType::HANDLE_TYPE_IBC_CHANNEL_CONNECT => Ok(CosmosSdkMsg::Other), - HandleType::HANDLE_TYPE_IBC_CHANNEL_CLOSE => Ok(CosmosSdkMsg::Other), + HandleType::HANDLE_TYPE_REPLY => Ok(DirectCosmosMsg::Other), + HandleType::HANDLE_TYPE_IBC_CHANNEL_OPEN => Ok(DirectCosmosMsg::Other), + HandleType::HANDLE_TYPE_IBC_CHANNEL_CONNECT => Ok(DirectCosmosMsg::Other), + HandleType::HANDLE_TYPE_IBC_CHANNEL_CLOSE => Ok(DirectCosmosMsg::Other), HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE | HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER => { Self::try_parse_ibc_recv_packet(bytes) @@ -687,7 +686,7 @@ impl CosmosSdkMsg { match raw_msg.packet.clone().into_option() { None => Err(EnclaveError::FailedToDeserialize), - Some(packet) => Ok(CosmosSdkMsg::MsgAcknowledgement { + Some(packet) => Ok(DirectCosmosMsg::MsgAcknowledgement { packet: Packet { sequence: packet.sequence, source_port: packet.source_port, @@ -715,7 +714,7 @@ impl CosmosSdkMsg { match raw_msg.packet.clone().into_option() { None => Err(EnclaveError::FailedToDeserialize), - Some(packet) => Ok(CosmosSdkMsg::MsgTimeout { + Some(packet) => Ok(DirectCosmosMsg::MsgTimeout { packet: Packet { sequence: packet.sequence, source_port: packet.source_port, @@ -743,7 +742,7 @@ impl CosmosSdkMsg { match raw_msg.packet.into_option() { None => Err(EnclaveError::FailedToDeserialize), - Some(packet) => Ok(CosmosSdkMsg::MsgRecvPacket { + Some(packet) => Ok(DirectCosmosMsg::MsgRecvPacket { packet: Packet { sequence: packet.sequence, source_port: packet.source_port, @@ -777,10 +776,9 @@ impl CosmosSdkMsg { let sender = CanonicalAddr::from_human(&HumanAddr(raw_msg.sender)) .map_err(|_| EnclaveError::FailedToDeserialize)?; - Ok(CosmosSdkMsg::MsgMigrateContract { + Ok(DirectCosmosMsg::MsgMigrateContract { sender, msg: raw_msg.msg, - code_id: raw_msg.code_id, contract: HumanAddr(raw_msg.contract), }) } @@ -801,7 +799,7 @@ impl CosmosSdkMsg { let callback_sig = Some(raw_msg.callback_sig); - Ok(CosmosSdkMsg::MsgInstantiateContract { + Ok(DirectCosmosMsg::MsgInstantiateContract { sender: CanonicalAddr(Binary(raw_msg.sender)), init_msg: raw_msg.init_msg, init_funds, @@ -843,7 +841,7 @@ impl CosmosSdkMsg { let callback_sig = Some(raw_msg.callback_sig); - Ok(CosmosSdkMsg::MsgExecuteContract { + Ok(DirectCosmosMsg::MsgExecuteContract { sender: CanonicalAddr(Binary(raw_msg.sender)), contract, msg: raw_msg.msg, @@ -876,13 +874,13 @@ impl CosmosSdkMsg { pub fn sender(&self) -> Option<&CanonicalAddr> { match self { - CosmosSdkMsg::MsgExecuteContract { sender, .. } - | CosmosSdkMsg::MsgInstantiateContract { sender, .. } - | CosmosSdkMsg::MsgMigrateContract { sender, .. } => Some(sender), - CosmosSdkMsg::MsgRecvPacket { .. } => None, - CosmosSdkMsg::MsgAcknowledgement { .. } => None, - CosmosSdkMsg::MsgTimeout { .. } => None, - CosmosSdkMsg::Other => None, + DirectCosmosMsg::MsgExecuteContract { sender, .. } + | DirectCosmosMsg::MsgInstantiateContract { sender, .. } + | DirectCosmosMsg::MsgMigrateContract { sender, .. } => Some(sender), + DirectCosmosMsg::MsgRecvPacket { .. } => None, + DirectCosmosMsg::MsgAcknowledgement { .. } => None, + DirectCosmosMsg::MsgTimeout { .. } => None, + DirectCosmosMsg::Other => None, } } } From d52d739712fbf52ffdcc708ea66de2fc6d1448d8 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 13 Jun 2023 11:36:16 +0300 Subject: [PATCH 023/164] Fix protobuf stuff & rename test functions --- x/compute/internal/keeper/keeper.go | 17 +++++++++++------ .../keeper/secret_contracts_migrate_test.go | 9 +++++---- .../keeper/secret_contracts_utils_test.go | 4 ++-- x/compute/internal/keeper/test_common.go | 3 ++- x/compute/internal/types/types.go | 7 +------ 5 files changed, 21 insertions(+), 19 deletions(-) diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index 8010eea8d..4110cae23 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -510,7 +510,7 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator sdk.AccAddre // persist instance createdAt := types.NewAbsoluteTxPosition(ctx) - contractInfo := types.NewContractInfo(codeID, creator, admin, adminProof, label, createdAt) + contractInfo := types.NewContractInfo(codeID, creator, admin.String(), adminProof, label, createdAt) historyEntry := contractInfo.InitialHistory(initMsg) k.addToContractCodeSecondaryIndex(ctx, contractAddress, historyEntry) @@ -537,7 +537,7 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator sdk.AccAddre case *v1wasmTypes.Response: // persist instance first createdAt := types.NewAbsoluteTxPosition(ctx) - contractInfo := types.NewContractInfo(codeID, creator, admin, adminProof, label, createdAt) + contractInfo := types.NewContractInfo(codeID, creator, admin.String(), adminProof, label, createdAt) // check for IBC flag report, err := k.wasmer.AnalyzeCode(codeInfo.CodeHash) @@ -1208,10 +1208,10 @@ func (k Keeper) UpdateContractAdmin(ctx sdk.Context, contractAddress, caller, ne if contractInfo == nil { return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "unknown contract") } - if contractInfo.Admin.String() != caller.String() { + if contractInfo.Admin != caller.String() { return sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "caller is not the admin") } - contractInfo.Admin = newAdmin + contractInfo.Admin = newAdmin.String() k.setContractInfo(ctx, contractAddress, contractInfo) ctx.EventManager().EmitEvent(sdk.NewEvent( types.EventTypeUpdateContractAdmin, @@ -1264,7 +1264,7 @@ func (k Keeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller return nil, err } - if contractInfo.Admin.String() != caller.String() { + if contractInfo.Admin != caller.String() { return nil, sdkerrors.Wrap(types.ErrMigrationFailed, "requires migrate from admin") } @@ -1275,6 +1275,11 @@ func (k Keeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller adminProof := k.GetContractInfo(ctx, contractAddress).AdminProof admin := k.GetContractInfo(ctx, contractAddress).Admin + adminAddr, err := sdk.AccAddressFromBech32(admin) + if err != nil { + return nil, sdkerrors.Wrap(types.ErrMigrationFailed, err.Error()) + } + // prepare querier querier := QueryHandler{ Ctx: ctx, @@ -1285,7 +1290,7 @@ func (k Keeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller // instantiate wasm contract gas := gasForContract(ctx) - response, newContractKey, proof, gasUsed, err := k.wasmer.Migrate(newCodeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, gasMeter(ctx), gas, verificationInfo, admin, adminProof) + response, newContractKey, proof, gasUsed, err := k.wasmer.Migrate(newCodeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, gasMeter(ctx), gas, verificationInfo, adminAddr, adminProof) consumeGas(ctx, gasUsed) // update contract key with new one diff --git a/x/compute/internal/keeper/secret_contracts_migrate_test.go b/x/compute/internal/keeper/secret_contracts_migrate_test.go index c643577b5..3beaac3a4 100644 --- a/x/compute/internal/keeper/secret_contracts_migrate_test.go +++ b/x/compute/internal/keeper/secret_contracts_migrate_test.go @@ -1,10 +1,11 @@ package keeper import ( - "github.com/stretchr/testify/require" "math" "testing" + "github.com/stretchr/testify/require" + sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -19,7 +20,7 @@ func TestMigrateContract(t *testing.T) { require.Empty(t, execErr) require.Empty(t, data) - _, err := MigrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"migrate":{}}`, true, true, math.MaxUint64) + _, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"migrate":{}}`, true, true, math.MaxUint64) require.Empty(t, err) _, _, data, _, _, execErr = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"new_function":{}}`, true, true, defaultGasForTests, 0) @@ -38,7 +39,7 @@ func TestMigrateWithStorage(t *testing.T) { require.Empty(t, execErr) require.Empty(t, data) - _, err := MigrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"migrate":{}}`, true, true, math.MaxUint64) + _, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"migrate":{}}`, true, true, math.MaxUint64) require.Empty(t, err) _, _, data, _, _, execErr = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"new_function_with_storage":{}}`, true, true, defaultGasForTests, 0) @@ -57,6 +58,6 @@ func TestMigrateContractFromDifferentAccount(t *testing.T) { require.Empty(t, execErr) require.Empty(t, data) - _, err := MigrateHelper(t, keeper, ctx, newCodeId, contractAddress, WalletB, privKeyB, `{"migrate":{}}`, false, true, math.MaxUint64) + _, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, WalletB, privKeyB, `{"migrate":{}}`, false, true, math.MaxUint64) require.NotNil(t, err) } diff --git a/x/compute/internal/keeper/secret_contracts_utils_test.go b/x/compute/internal/keeper/secret_contracts_utils_test.go index 62968b998..82f1debcf 100644 --- a/x/compute/internal/keeper/secret_contracts_utils_test.go +++ b/x/compute/internal/keeper/secret_contracts_utils_test.go @@ -697,7 +697,7 @@ type v1QueryResponse struct { Get GetResponse `json:"get"` } -func MigrateHelper( +func migrateHelper( t *testing.T, keeper Keeper, ctx sdk.Context, newCodeId uint64, contractAddress sdk.AccAddress, txSender sdk.AccAddress, senderPrivKey crypto.PrivKey, migrateMsg string, @@ -727,7 +727,7 @@ func MigrateHelper( log.NewNopLogger(), ).WithGasMeter(gasMeter) - ctx = PrepareMigrateSignedTx(t, keeper, ctx, contractAddress.String(), txSender, senderPrivKey, migrateMsgBz, newCodeId) + ctx = prepareMigrateSignedTx(t, keeper, ctx, contractAddress.String(), txSender, senderPrivKey, migrateMsgBz, newCodeId) // reset value before test keeper.LastMsgManager.SetMarker(false) diff --git a/x/compute/internal/keeper/test_common.go b/x/compute/internal/keeper/test_common.go index 46dc8b80f..d2cd39dbc 100644 --- a/x/compute/internal/keeper/test_common.go +++ b/x/compute/internal/keeper/test_common.go @@ -686,6 +686,7 @@ func PrepareInitSignedTx(t *testing.T, keeper Keeper, ctx sdk.Context, creator s Label: "demo contract 1", InitMsg: encMsg, InitFunds: funds, + Admin: creator.String(), } newTx := NewTestTx(&initMsg, creatorAcc, privKey) @@ -695,7 +696,7 @@ func PrepareInitSignedTx(t *testing.T, keeper Keeper, ctx sdk.Context, creator s return ctx.WithTxBytes(txBytes) } -func PrepareMigrateSignedTx(t *testing.T, keeper Keeper, ctx sdk.Context, contractAddress string, creator sdk.AccAddress, privKey crypto.PrivKey, encMsg []byte, codeID uint64) sdk.Context { +func prepareMigrateSignedTx(t *testing.T, keeper Keeper, ctx sdk.Context, contractAddress string, creator sdk.AccAddress, privKey crypto.PrivKey, encMsg []byte, codeID uint64) sdk.Context { creatorAcc, err := ante.GetSignerAcc(ctx, keeper.accountKeeper, creator) require.NoError(t, err) diff --git a/x/compute/internal/types/types.go b/x/compute/internal/types/types.go index 9dd967ee7..30f4df47e 100644 --- a/x/compute/internal/types/types.go +++ b/x/compute/internal/types/types.go @@ -56,7 +56,7 @@ func NewCodeInfo(codeHash []byte, creator sdk.AccAddress, source string, builder } // NewContractInfo creates a new instance of a given WASM contract info -func NewContractInfo(codeID uint64, creator sdk.AccAddress, admin sdk.AccAddress, adminProof []byte, label string, createdAt *AbsoluteTxPosition) ContractInfo { +func NewContractInfo(codeID uint64, creator sdk.AccAddress, admin string, adminProof []byte, label string, createdAt *AbsoluteTxPosition) ContractInfo { return ContractInfo{ CodeID: codeID, Creator: creator, @@ -344,8 +344,3 @@ func (c *ContractInfo) AddMigration(ctx sdk.Context, codeID uint64, msg []byte) c.CodeID = codeID return h } - -// AdminAddr convert into sdk.AccAddress or nil when not set -func (c *ContractInfo) AdminAddr() sdk.AccAddress { - return c.Admin -} From 0bafad52bca8e7fc97c5193efbfb603dc40ad9fb Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 13 Jun 2023 13:33:21 +0300 Subject: [PATCH 024/164] Cont. to fix protobuf stuff & rename things Also remove duplicate output events --- .../src/contract_validation.rs | 10 +- .../contract_address_validation.rs | 18 ++-- .../src/input_validation/msg_validation.rs | 20 ++-- .../send_funds_validations.rs | 18 ++-- .../src/input_validation/sender_validation.rs | 18 ++-- .../enclaves/shared/cosmos-types/src/types.rs | 92 +++++++++++-------- x/compute/internal/keeper/keeper.go | 6 -- 7 files changed, 98 insertions(+), 84 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index e9fd389c2..e76d58535 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -8,7 +8,7 @@ use cw_types_generic::BaseEnv; use cw_types_v010::types::{CanonicalAddr, Coin, HumanAddr}; use enclave_cosmos_types::traits::CosmosAminoPubkey; use enclave_cosmos_types::types::{ - ContractCode, CosmosPubKey, CosmosSdkMsg, HandleType, SigInfo, SignDoc, StdSignDoc, + ContractCode, CosmosPubKey, DirectSdkMsg, HandleType, SigInfo, SignDoc, StdSignDoc, }; use enclave_crypto::traits::VerifyingKey; use enclave_crypto::{sha_256, AESKey, Hmac, Kdf, HASH_SIZE, KEY_MANAGER}; @@ -526,7 +526,7 @@ fn get_signer( fn get_messages( sign_info: &SigInfo, handle_type: HandleType, -) -> Result, EnclaveError> { +) -> Result, EnclaveError> { use cosmos_proto::tx::signing::SignMode::*; match sign_info.sign_mode { SIGN_MODE_DIRECT => { @@ -541,7 +541,7 @@ fn get_messages( warn!("failure to parse StdSignDoc: {:?}", err); EnclaveError::FailedTxVerification })?; - let messages: Result, _> = sign_doc + let messages: Result, _> = sign_doc .msgs .iter() .map(|x| x.clone().into_cosmwasm_msg()) @@ -577,7 +577,7 @@ fn get_messages( ); EnclaveError::FailedTxVerification })?; - let messages: Result, _> = sign_doc + let messages: Result, _> = sign_doc .msgs .iter() .map(|x| x.clone().into_cosmwasm_msg()) @@ -638,7 +638,7 @@ fn verify_callback_sig_impl( } fn verify_message_params( - messages: &[CosmosSdkMsg], + messages: &[DirectSdkMsg], sender: &CanonicalAddr, sent_funds: &[Coin], contract_address: &HumanAddr, diff --git a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/contract_address_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/contract_address_validation.rs index e3cc83423..13f22fbd4 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/contract_address_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/contract_address_validation.rs @@ -1,23 +1,23 @@ use cw_types_v010::types::HumanAddr; use enclave_cosmos_types::types::{ - CosmosSdkMsg, FungibleTokenPacketData, IbcHooksIncomingTransferMsg, + DirectSdkMsg, FungibleTokenPacketData, IbcHooksIncomingTransferMsg, IbcHooksOutgoingTransferMemo, Packet, }; use log::*; /// Check that the contract listed in the cosmos sdk message matches the one in env -pub fn verify_contract_address(msg: &CosmosSdkMsg, contract_address: &HumanAddr) -> bool { +pub fn verify_contract_address(msg: &DirectSdkMsg, contract_address: &HumanAddr) -> bool { // Contract address is relevant only to execute, since during sending an instantiate message the contract address is not yet known match msg { - CosmosSdkMsg::MsgExecuteContract { contract, .. } => { + DirectSdkMsg::MsgExecuteContract { contract, .. } => { verify_msg_execute_contract_address(contract_address, contract) } - CosmosSdkMsg::MsgMigrateContract { contract, .. } => { + DirectSdkMsg::MsgMigrateContract { contract, .. } => { verify_msg_migrate_contract_address(contract_address, contract) } // During sending an instantiate message the contract address is not yet known - CosmosSdkMsg::MsgInstantiateContract { .. } => true, - CosmosSdkMsg::MsgRecvPacket { + DirectSdkMsg::MsgInstantiateContract { .. } => true, + DirectSdkMsg::MsgRecvPacket { packet: Packet { destination_port, @@ -26,19 +26,19 @@ pub fn verify_contract_address(msg: &CosmosSdkMsg, contract_address: &HumanAddr) }, .. } => verify_contract_address_msg_recv_packet(destination_port, data, contract_address), - CosmosSdkMsg::MsgAcknowledgement { + DirectSdkMsg::MsgAcknowledgement { packet: Packet { source_port, data, .. }, .. } - | CosmosSdkMsg::MsgTimeout { + | DirectSdkMsg::MsgTimeout { packet: Packet { source_port, data, .. }, .. } => verify_contract_address_msg_ack_or_timeout(source_port, data, contract_address), - CosmosSdkMsg::Other => false, + DirectSdkMsg::Other => false, } } diff --git a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs index 087eb62c8..2ac948596 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs @@ -1,7 +1,7 @@ use cw_types_v010::{encoding::Binary, types::CanonicalAddr}; use cw_types_v1::ibc::IbcPacketReceiveMsg; use enclave_cosmos_types::types::{ - is_transfer_ack_error, CosmosSdkMsg, FungibleTokenPacketData, HandleType, IBCLifecycleComplete, + is_transfer_ack_error, DirectSdkMsg, FungibleTokenPacketData, HandleType, IBCLifecycleComplete, IBCLifecycleCompleteOptions, IBCPacketAckMsg, IBCPacketTimeoutMsg, IbcHooksIncomingTransferMsg, IncentivizedAcknowledgement, Packet, }; @@ -12,32 +12,32 @@ use crate::types::SecretMessage; /// Get the cosmwasm message that contains the encrypted message pub fn verify_and_get_sdk_msg<'sd>( - messages: &'sd [CosmosSdkMsg], + messages: &'sd [DirectSdkMsg], msg_sender: &CanonicalAddr, sent_msg: &SecretMessage, handle_type: HandleType, -) -> Option<&'sd CosmosSdkMsg> { +) -> Option<&'sd DirectSdkMsg> { trace!("get_verified_msg: {:?}", messages); messages.iter().find(|&m| match m { - CosmosSdkMsg::Other => false, - CosmosSdkMsg::MsgExecuteContract { msg, sender, .. } - | CosmosSdkMsg::MsgInstantiateContract { + DirectSdkMsg::Other => false, + DirectSdkMsg::MsgExecuteContract { msg, sender, .. } + | DirectSdkMsg::MsgInstantiateContract { init_msg: msg, sender, .. } - | CosmosSdkMsg::MsgMigrateContract { msg, sender, .. } => { + | DirectSdkMsg::MsgMigrateContract { msg, sender, .. } => { msg_sender == sender && &sent_msg.to_vec() == msg } - CosmosSdkMsg::MsgRecvPacket { packet, .. } => match handle_type { + DirectSdkMsg::MsgRecvPacket { packet, .. } => match handle_type { HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE => verify_ibc_packet_recv(sent_msg, packet), HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER => { verify_ibc_wasm_hooks_incoming_transfer(sent_msg, packet) } _ => false, }, - CosmosSdkMsg::MsgAcknowledgement { + DirectSdkMsg::MsgAcknowledgement { packet, acknowledgement, signer, @@ -51,7 +51,7 @@ pub fn verify_and_get_sdk_msg<'sd>( } _ => false, }, - CosmosSdkMsg::MsgTimeout { packet, signer, .. } => match handle_type { + DirectSdkMsg::MsgTimeout { packet, signer, .. } => match handle_type { HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT => { verify_ibc_packet_timeout(sent_msg, packet, signer) } diff --git a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/send_funds_validations.rs b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/send_funds_validations.rs index 1ccfa08b4..faa0d6647 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/send_funds_validations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/send_funds_validations.rs @@ -1,18 +1,18 @@ use crate::ibc_denom_utils::{get_denom_prefix, parse_denom_trace, receiver_chain_is_source}; use cw_types_v010::types::Coin; -use enclave_cosmos_types::types::{CosmosSdkMsg, FungibleTokenPacketData, Packet}; +use enclave_cosmos_types::types::{DirectSdkMsg, FungibleTokenPacketData, Packet}; use log::*; /// Check that the funds listed in the cosmwasm message matches the ones in env -pub fn verify_sent_funds(msg: &CosmosSdkMsg, sent_funds_msg: &[Coin]) -> bool { +pub fn verify_sent_funds(msg: &DirectSdkMsg, sent_funds_msg: &[Coin]) -> bool { match msg { - CosmosSdkMsg::MsgExecuteContract { sent_funds, .. } - | CosmosSdkMsg::MsgInstantiateContract { + DirectSdkMsg::MsgExecuteContract { sent_funds, .. } + | DirectSdkMsg::MsgInstantiateContract { init_funds: sent_funds, .. } => sent_funds_msg == sent_funds, - CosmosSdkMsg::Other => false, - CosmosSdkMsg::MsgRecvPacket { + DirectSdkMsg::Other => false, + DirectSdkMsg::MsgRecvPacket { packet: Packet { data, @@ -40,9 +40,9 @@ pub fn verify_sent_funds(msg: &CosmosSdkMsg, sent_funds_msg: &[Coin]) -> bool { sent_funds_msg.is_empty() } } - CosmosSdkMsg::MsgAcknowledgement { .. } - | CosmosSdkMsg::MsgTimeout { .. } - | CosmosSdkMsg::MsgMigrateContract { .. } => sent_funds_msg.is_empty(), + DirectSdkMsg::MsgAcknowledgement { .. } + | DirectSdkMsg::MsgTimeout { .. } + | DirectSdkMsg::MsgMigrateContract { .. } => sent_funds_msg.is_empty(), } } diff --git a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/sender_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/sender_validation.rs index d2f7cf762..d0511d9bf 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/sender_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/sender_validation.rs @@ -1,19 +1,19 @@ use cw_types_v010::types::CanonicalAddr; -use enclave_cosmos_types::types::CosmosSdkMsg; +use enclave_cosmos_types::types::DirectSdkMsg; use log::*; -pub fn verify_sender(sdk_msg: &CosmosSdkMsg, sender: &CanonicalAddr) -> Option { +pub fn verify_sender(sdk_msg: &DirectSdkMsg, sender: &CanonicalAddr) -> Option { match sdk_msg { - CosmosSdkMsg::MsgRecvPacket { .. } - | CosmosSdkMsg::MsgAcknowledgement { .. } - | CosmosSdkMsg::MsgTimeout { .. } => { + DirectSdkMsg::MsgRecvPacket { .. } + | DirectSdkMsg::MsgAcknowledgement { .. } + | DirectSdkMsg::MsgTimeout { .. } => { // No sender to verify. // Going to pass null sender to the contract if all other checks pass. } - CosmosSdkMsg::MsgExecuteContract { .. } - | CosmosSdkMsg::MsgInstantiateContract { .. } - | CosmosSdkMsg::MsgMigrateContract { .. } - | CosmosSdkMsg::Other => { + DirectSdkMsg::MsgExecuteContract { .. } + | DirectSdkMsg::MsgInstantiateContract { .. } + | DirectSdkMsg::MsgMigrateContract { .. } + | DirectSdkMsg::Other => { if sdk_msg.sender() != Some(sender) { trace!( "sender {:?} did not match sdk message sender: {:?}", diff --git a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs index 1c6f9203e..7dfa805c8 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs @@ -220,7 +220,7 @@ pub struct StdSignDoc { pub account_number: String, pub chain_id: String, pub memo: String, - pub msgs: Vec, + pub msgs: Vec, pub sequence: String, } @@ -257,7 +257,7 @@ impl SignDoc { #[derive(Debug)] pub struct TxBody { - pub messages: Vec, + pub messages: Vec, // Leaving this here for discoverability. We can use this, but don't verify it today. #[allow(dead_code)] memo: (), @@ -279,7 +279,7 @@ impl TxBody { let messages = tx_body .messages .into_iter() - .map(|any| DirectCosmosMsg::from_bytes(&any.value, handle_type)) + .map(|any| DirectSdkMsg::from_bytes(&any.value, handle_type)) .collect::, _>>()?; Ok(TxBody { @@ -292,7 +292,7 @@ impl TxBody { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] #[serde(rename_all = "snake_case", tag = "type", content = "value")] -pub enum AminoJsonCosmosMsg { +pub enum AminoSdkMsg { #[serde(alias = "wasm/MsgExecuteContract")] Execute { sender: HumanAddr, @@ -330,8 +330,8 @@ pub fn deserialize_ignore_any<'de, D: serde::Deserializer<'de>, T: Default>( serde::de::IgnoredAny::deserialize(deserializer).map(|_| T::default()) } -impl AminoJsonCosmosMsg { - pub fn into_cosmwasm_msg(self) -> Result { +impl AminoSdkMsg { + pub fn into_cosmwasm_msg(self) -> Result { match self { Self::Migrate { sender, @@ -340,21 +340,29 @@ impl AminoJsonCosmosMsg { code_id, } => { let sender = CanonicalAddr::from_human(&sender).map_err(|err| { - warn!("failed to turn human addr to canonical addr when parsing CosmWasmMsg: {:?}", err); + warn!("failed to turn human addr to canonical addr when parsing DirectSdkMsg: {:?}", err); EnclaveError::FailedToDeserialize })?; let msg = Binary::from_base64(&msg).map_err(|err| { warn!( - "failed to parse base64 msg when parsing CosmWasmMsg: {:?}", + "failed to parse base64 msg when parsing DirectSdkMsg: {:?}", err ); EnclaveError::FailedToDeserialize })?; let msg = msg.0; - Ok(DirectCosmosMsg::MsgMigrateContract { + let code_id = code_id.parse::().map_err(|err| { + warn!( + "failed to parse code_id as u64 when parsing DirectSdkMsg: {:?}", + err + ); + EnclaveError::FailedToDeserialize + })?; + Ok(DirectSdkMsg::MsgMigrateContract { sender, msg, contract, + code_id, }) } Self::Execute { @@ -365,18 +373,18 @@ impl AminoJsonCosmosMsg { callback_sig, } => { let sender = CanonicalAddr::from_human(&sender).map_err(|err| { - warn!("failed to turn human addr to canonical addr when parsing CosmWasmMsg: {:?}", err); + warn!("failed to turn human addr to canonical addr when parsing DirectSdkMsg: {:?}", err); EnclaveError::FailedToDeserialize })?; let msg = Binary::from_base64(&msg).map_err(|err| { warn!( - "failed to parse base64 msg when parsing CosmWasmMsg: {:?}", + "failed to parse base64 msg when parsing DirectSdkMsg: {:?}", err ); EnclaveError::FailedToDeserialize })?; let msg = msg.0; - Ok(DirectCosmosMsg::MsgExecuteContract { + Ok(DirectSdkMsg::MsgExecuteContract { sender, contract, msg, @@ -390,23 +398,31 @@ impl AminoJsonCosmosMsg { init_funds, label, callback_sig, - code_id: _, + code_id, admin, } => { let sender = CanonicalAddr::from_human(&sender).map_err(|err| { - warn!("failed to turn human addr to canonical addr when parsing CosmWasmMsg: {:?}", err); + warn!("failed to turn human addr to canonical addr when parsing DirectSdkMsg: {:?}", err); EnclaveError::FailedToDeserialize })?; let init_msg = Binary::from_base64(&init_msg).map_err(|err| { warn!( - "failed to parse base64 init_msg when parsing CosmWasmMsg: {:?}", + "failed to parse base64 init_msg when parsing DirectSdkMsg: {:?}", err ); EnclaveError::FailedToDeserialize })?; let init_msg = init_msg.0; - Ok(DirectCosmosMsg::MsgInstantiateContract { + let code_id = code_id.parse::().map_err(|err| { + warn!( + "failed to parse code_id as u64 when parsing DirectSdkMsg: {:?}", + err + ); + EnclaveError::FailedToDeserialize + })?; + Ok(DirectSdkMsg::MsgInstantiateContract { sender, + code_id, init_msg, init_funds, label, @@ -414,7 +430,7 @@ impl AminoJsonCosmosMsg { admin, }) } - Self::Other => Ok(DirectCosmosMsg::Other), + Self::Other => Ok(DirectSdkMsg::Other), } } } @@ -572,7 +588,7 @@ pub struct Packet { } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -pub enum DirectCosmosMsg { +pub enum DirectSdkMsg { // CosmWasm: MsgExecuteContract { sender: CanonicalAddr, @@ -588,11 +604,13 @@ pub enum DirectCosmosMsg { label: String, callback_sig: Option>, admin: HumanAddr, + code_id: u64, }, MsgMigrateContract { sender: CanonicalAddr, contract: HumanAddr, msg: Vec, + code_id: u64, }, // IBC: // MsgChannelOpenInit {}, // TODO @@ -625,7 +643,7 @@ pub enum DirectCosmosMsg { Other, } -impl DirectCosmosMsg { +impl DirectSdkMsg { pub fn from_bytes(bytes: &[u8], handle_type: HandleType) -> Result { // Assaf: This function needs a refactor, as some protobufs are // compatible, e.g. try_parse_execute succeeds in parsing MsgRecvPacket as @@ -635,10 +653,10 @@ impl DirectCosmosMsg { HandleType::HANDLE_TYPE_EXECUTE => Self::try_parse_execute(bytes) .or_else(|_| Self::try_parse_instantiate(bytes)) .or_else(|_| Self::try_parse_migrate(bytes)), - HandleType::HANDLE_TYPE_REPLY => Ok(DirectCosmosMsg::Other), - HandleType::HANDLE_TYPE_IBC_CHANNEL_OPEN => Ok(DirectCosmosMsg::Other), - HandleType::HANDLE_TYPE_IBC_CHANNEL_CONNECT => Ok(DirectCosmosMsg::Other), - HandleType::HANDLE_TYPE_IBC_CHANNEL_CLOSE => Ok(DirectCosmosMsg::Other), + HandleType::HANDLE_TYPE_REPLY => Ok(DirectSdkMsg::Other), + HandleType::HANDLE_TYPE_IBC_CHANNEL_OPEN => Ok(DirectSdkMsg::Other), + HandleType::HANDLE_TYPE_IBC_CHANNEL_CONNECT => Ok(DirectSdkMsg::Other), + HandleType::HANDLE_TYPE_IBC_CHANNEL_CLOSE => Ok(DirectSdkMsg::Other), HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE | HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER => { Self::try_parse_ibc_recv_packet(bytes) @@ -686,7 +704,7 @@ impl DirectCosmosMsg { match raw_msg.packet.clone().into_option() { None => Err(EnclaveError::FailedToDeserialize), - Some(packet) => Ok(DirectCosmosMsg::MsgAcknowledgement { + Some(packet) => Ok(DirectSdkMsg::MsgAcknowledgement { packet: Packet { sequence: packet.sequence, source_port: packet.source_port, @@ -714,7 +732,7 @@ impl DirectCosmosMsg { match raw_msg.packet.clone().into_option() { None => Err(EnclaveError::FailedToDeserialize), - Some(packet) => Ok(DirectCosmosMsg::MsgTimeout { + Some(packet) => Ok(DirectSdkMsg::MsgTimeout { packet: Packet { sequence: packet.sequence, source_port: packet.source_port, @@ -742,7 +760,7 @@ impl DirectCosmosMsg { match raw_msg.packet.into_option() { None => Err(EnclaveError::FailedToDeserialize), - Some(packet) => Ok(DirectCosmosMsg::MsgRecvPacket { + Some(packet) => Ok(DirectSdkMsg::MsgRecvPacket { packet: Packet { sequence: packet.sequence, source_port: packet.source_port, @@ -776,10 +794,11 @@ impl DirectCosmosMsg { let sender = CanonicalAddr::from_human(&HumanAddr(raw_msg.sender)) .map_err(|_| EnclaveError::FailedToDeserialize)?; - Ok(DirectCosmosMsg::MsgMigrateContract { + Ok(DirectSdkMsg::MsgMigrateContract { sender, msg: raw_msg.msg, contract: HumanAddr(raw_msg.contract), + code_id: raw_msg.code_id, }) } @@ -799,13 +818,14 @@ impl DirectCosmosMsg { let callback_sig = Some(raw_msg.callback_sig); - Ok(DirectCosmosMsg::MsgInstantiateContract { + Ok(DirectSdkMsg::MsgInstantiateContract { sender: CanonicalAddr(Binary(raw_msg.sender)), init_msg: raw_msg.init_msg, init_funds, label: raw_msg.label, callback_sig, admin: HumanAddr(raw_msg.admin), + code_id: raw_msg.code_id, }) } @@ -841,7 +861,7 @@ impl DirectCosmosMsg { let callback_sig = Some(raw_msg.callback_sig); - Ok(DirectCosmosMsg::MsgExecuteContract { + Ok(DirectSdkMsg::MsgExecuteContract { sender: CanonicalAddr(Binary(raw_msg.sender)), contract, msg: raw_msg.msg, @@ -874,13 +894,13 @@ impl DirectCosmosMsg { pub fn sender(&self) -> Option<&CanonicalAddr> { match self { - DirectCosmosMsg::MsgExecuteContract { sender, .. } - | DirectCosmosMsg::MsgInstantiateContract { sender, .. } - | DirectCosmosMsg::MsgMigrateContract { sender, .. } => Some(sender), - DirectCosmosMsg::MsgRecvPacket { .. } => None, - DirectCosmosMsg::MsgAcknowledgement { .. } => None, - DirectCosmosMsg::MsgTimeout { .. } => None, - DirectCosmosMsg::Other => None, + DirectSdkMsg::MsgExecuteContract { sender, .. } + | DirectSdkMsg::MsgInstantiateContract { sender, .. } + | DirectSdkMsg::MsgMigrateContract { sender, .. } => Some(sender), + DirectSdkMsg::MsgRecvPacket { .. } => None, + DirectSdkMsg::MsgAcknowledgement { .. } => None, + DirectSdkMsg::MsgTimeout { .. } => None, + DirectSdkMsg::Other => None, } } } diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index 4110cae23..5285c4139 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -1343,12 +1343,6 @@ func (k Keeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller return data, nil case *v1wasmTypes.Response: - ctx.EventManager().EmitEvent(sdk.NewEvent( - types.EventTypeMigrate, - sdk.NewAttribute(types.AttributeKeyContractAddr, contractAddress.String()), - sdk.NewAttribute(types.AttributeKeyCodeID, strconv.FormatUint(newCodeID, 10)), - )) - data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res.Messages, res.Attributes, res.Events, res.Data, msg, verificationInfo) if err != nil { return nil, sdkerrors.Wrap(err, "dispatch") From 6e7384717c5c934daf573aad7c2c8b5ef63df221 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 13 Jun 2023 14:02:00 +0300 Subject: [PATCH 025/164] Implement ContractHistory query --- proto/secret/compute/v1beta1/query.proto | 4 - x/compute/internal/keeper/querier.go | 29 +-- x/compute/internal/types/query.pb.go | 270 +++++++---------------- x/compute/internal/types/query.pb.gw.go | 18 -- 4 files changed, 89 insertions(+), 232 deletions(-) diff --git a/proto/secret/compute/v1beta1/query.proto b/proto/secret/compute/v1beta1/query.proto index 094b9cb62..549942d5d 100644 --- a/proto/secret/compute/v1beta1/query.proto +++ b/proto/secret/compute/v1beta1/query.proto @@ -161,8 +161,6 @@ message QueryContractHistoryRequest { option (gogoproto.equal) = false; // address is the address of the contract to query string contract_address = 1; - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 2; } // QueryContractHistoryResponse is the response type for the @@ -172,6 +170,4 @@ message QueryContractHistoryResponse { repeated ContractCodeHistoryEntry entries = 1 [ (gogoproto.nullable) = false ]; - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; } \ No newline at end of file diff --git a/x/compute/internal/keeper/querier.go b/x/compute/internal/keeper/querier.go index 8f8a943fd..d1739b844 100644 --- a/x/compute/internal/keeper/querier.go +++ b/x/compute/internal/keeper/querier.go @@ -18,9 +18,15 @@ type GrpcQuerier struct { keeper Keeper } -func (q GrpcQuerier) ContractHistory(ctx context.Context, request *types.QueryContractHistoryRequest) (*types.QueryContractHistoryResponse, error) { - // TODO implement me - panic("implement me") +func (q GrpcQuerier) ContractHistory(c context.Context, req *types.QueryContractHistoryRequest) (*types.QueryContractHistoryResponse, error) { + contractAddress, err := sdk.AccAddressFromBech32(req.ContractAddress) + if err != nil { + return nil, err + } + + return &types.QueryContractHistoryResponse{ + Entries: q.keeper.GetContractHistory(sdk.UnwrapSDKContext(c), contractAddress), + }, nil } func NewGrpcQuerier(keeper Keeper) GrpcQuerier { @@ -33,11 +39,6 @@ func (q GrpcQuerier) ContractInfo(c context.Context, req *types.QueryByContractA return nil, err } - err = sdk.VerifyAddressFormat(contractAddress) - if err != nil { - return nil, err - } - response, err := queryContractInfo(sdk.UnwrapSDKContext(c), contractAddress, q.keeper) switch { case err != nil: @@ -76,10 +77,6 @@ func (q GrpcQuerier) QuerySecretContract(c context.Context, req *types.QuerySecr return nil, err } - if err := sdk.VerifyAddressFormat(contractAddress); err != nil { - return nil, err - } - ctx := sdk.UnwrapSDKContext(c).WithGasMeter(sdk.NewGasMeter(q.keeper.queryGasLimit)) response, err := q.keeper.QuerySmart(ctx, contractAddress, req.Query, false) @@ -130,10 +127,6 @@ func (q GrpcQuerier) CodeHashByContractAddress(c context.Context, req *types.Que return nil, err } - if err := sdk.VerifyAddressFormat(contractAddress); err != nil { - return nil, err - } - ctx := sdk.UnwrapSDKContext(c).WithGasMeter(sdk.NewGasMeter(q.keeper.queryGasLimit)) codeHashBz, err := queryCodeHashByAddress(ctx, contractAddress, q.keeper) @@ -171,10 +164,6 @@ func (q GrpcQuerier) LabelByAddress(c context.Context, req *types.QueryByContrac return nil, err } - if err := sdk.VerifyAddressFormat(contractAddress); err != nil { - return nil, err - } - ctx := sdk.UnwrapSDKContext(c).WithGasMeter(sdk.NewGasMeter(q.keeper.queryGasLimit)) response, err := queryContractInfo(ctx, contractAddress, q.keeper) diff --git a/x/compute/internal/types/query.pb.go b/x/compute/internal/types/query.pb.go index 85895444a..c61a84011 100644 --- a/x/compute/internal/types/query.pb.go +++ b/x/compute/internal/types/query.pb.go @@ -8,7 +8,7 @@ import ( context "context" fmt "fmt" types "github.com/cosmos/cosmos-sdk/types" - query "github.com/cosmos/cosmos-sdk/types/query" + _ "github.com/cosmos/cosmos-sdk/types/query" _ "github.com/gogo/protobuf/gogoproto" grpc1 "github.com/gogo/protobuf/grpc" proto "github.com/gogo/protobuf/proto" @@ -653,8 +653,6 @@ var xxx_messageInfo_DecryptedAnswers proto.InternalMessageInfo type QueryContractHistoryRequest struct { // address is the address of the contract to query ContractAddress string `protobuf:"bytes,1,opt,name=contract_address,json=contractAddress,proto3" json:"contract_address,omitempty"` - // pagination defines an optional pagination for the request. - Pagination *query.PageRequest `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } func (m *QueryContractHistoryRequest) Reset() { *m = QueryContractHistoryRequest{} } @@ -694,8 +692,6 @@ var xxx_messageInfo_QueryContractHistoryRequest proto.InternalMessageInfo // Query/ContractHistory RPC method type QueryContractHistoryResponse struct { Entries []ContractCodeHistoryEntry `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries"` - // pagination defines the pagination in the response. - Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } func (m *QueryContractHistoryResponse) Reset() { *m = QueryContractHistoryResponse{} } @@ -757,87 +753,85 @@ func init() { } var fileDescriptor_7735281c5fa969d4 = []byte{ - // 1279 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x57, 0x4d, 0x6c, 0x1b, 0x45, - 0x14, 0xf6, 0xb4, 0x4e, 0xd2, 0xbc, 0xa4, 0x49, 0x3a, 0xa4, 0xa9, 0xeb, 0x14, 0xa7, 0x5d, 0x4a, - 0xf3, 0x57, 0xbc, 0xb5, 0x13, 0x8a, 0x54, 0x71, 0x49, 0xd2, 0x40, 0x83, 0x02, 0x14, 0xf7, 0x80, - 0x84, 0x8a, 0xac, 0xf1, 0x7a, 0x62, 0xaf, 0xea, 0xec, 0xb8, 0x3b, 0xe3, 0x26, 0x16, 0x0a, 0x07, - 0x4e, 0x1c, 0x91, 0xf8, 0x11, 0x82, 0x0b, 0x27, 0xa8, 0x38, 0x20, 0x71, 0xe5, 0xc2, 0x35, 0x07, - 0x0e, 0x91, 0xb8, 0x70, 0xaa, 0x20, 0xe1, 0x80, 0xb8, 0x73, 0x47, 0x3b, 0x33, 0xbb, 0xd9, 0xb5, - 0xd7, 0xb1, 0x1d, 0x0e, 0xdc, 0x76, 0x66, 0xde, 0x7b, 0xdf, 0xf7, 0xde, 0x9b, 0x79, 0xef, 0x2d, - 0x18, 0x9c, 0x5a, 0x2e, 0x15, 0xa6, 0xc5, 0xb6, 0xeb, 0x0d, 0x41, 0xcd, 0x27, 0xb9, 0x12, 0x15, - 0x24, 0x67, 0x3e, 0x6e, 0x50, 0xb7, 0x99, 0xad, 0xbb, 0x4c, 0x30, 0x3c, 0xa5, 0x64, 0xb2, 0x5a, - 0x26, 0xab, 0x65, 0xd2, 0x93, 0x15, 0x56, 0x61, 0x52, 0xc4, 0xf4, 0xbe, 0x94, 0x74, 0xba, 0x93, - 0x45, 0xd1, 0xac, 0x53, 0xae, 0x65, 0xa6, 0x2b, 0x8c, 0x55, 0x6a, 0xd4, 0x94, 0xab, 0x52, 0x63, - 0xcb, 0xa4, 0xdb, 0x75, 0xa1, 0xe1, 0xd2, 0x57, 0xf4, 0x21, 0xa9, 0xdb, 0x26, 0x71, 0x1c, 0x26, - 0x88, 0xb0, 0x99, 0xe3, 0xab, 0xbe, 0x60, 0x31, 0xbe, 0xcd, 0xb8, 0x59, 0x22, 0x9c, 0x9a, 0xa4, - 0x64, 0xd9, 0x01, 0x80, 0xb7, 0xd0, 0x42, 0x0b, 0x61, 0x21, 0xe9, 0x4a, 0x20, 0x55, 0x27, 0x15, - 0xdb, 0x91, 0x16, 0x95, 0xac, 0xf1, 0x3e, 0xa4, 0xdf, 0xf1, 0x24, 0x1e, 0x48, 0xda, 0x6b, 0xcc, - 0x11, 0x2e, 0xb1, 0x44, 0x81, 0x3e, 0x6e, 0x50, 0x2e, 0xf0, 0x3c, 0x4c, 0x58, 0x7a, 0xab, 0x48, - 0xca, 0x65, 0x97, 0x72, 0x9e, 0x42, 0x57, 0xd1, 0xdc, 0x70, 0x61, 0xdc, 0xdf, 0x5f, 0x51, 0xdb, - 0x78, 0x12, 0x06, 0x24, 0x54, 0xea, 0xcc, 0x55, 0x34, 0x37, 0x5a, 0x50, 0x0b, 0x63, 0x11, 0x9e, - 0x93, 0xe6, 0x57, 0x9b, 0x9b, 0xa4, 0x44, 0x6b, 0xbe, 0xdd, 0x49, 0x18, 0xa8, 0x79, 0x6b, 0x6d, - 0x4c, 0x2d, 0x8c, 0x37, 0xe0, 0x79, 0x2d, 0xbc, 0x16, 0x35, 0xde, 0x3f, 0x1d, 0xc3, 0x84, 0xc9, - 0xc0, 0x56, 0x99, 0x6e, 0x94, 0x7d, 0x13, 0x97, 0x60, 0xc8, 0x62, 0x65, 0x5a, 0xb4, 0xcb, 0x52, - 0x33, 0x59, 0x18, 0xb4, 0xe4, 0xb9, 0x91, 0x83, 0xe9, 0xd8, 0x40, 0xf0, 0x3a, 0x73, 0x38, 0xc5, - 0x18, 0x92, 0x65, 0x22, 0x88, 0x54, 0x1a, 0x2d, 0xc8, 0x6f, 0xe3, 0x2b, 0x04, 0x97, 0xa5, 0x8e, - 0x2f, 0xbd, 0xe1, 0x6c, 0xb1, 0x40, 0xa3, 0x8f, 0xd8, 0x15, 0x60, 0x34, 0x6c, 0x42, 0x86, 0x70, - 0x24, 0x7f, 0x3d, 0x1b, 0x7f, 0xf3, 0xb2, 0x61, 0xd9, 0xd5, 0x73, 0x07, 0xcf, 0x66, 0xd0, 0xdf, - 0xcf, 0x66, 0x12, 0x85, 0x88, 0x0d, 0xe3, 0x4b, 0x04, 0x97, 0xc2, 0x1b, 0xef, 0xda, 0xa2, 0xea, - 0xe3, 0xfd, 0xcf, 0xd4, 0x3e, 0x84, 0x4c, 0x24, 0x6c, 0xfc, 0x38, 0x49, 0x3a, 0x76, 0x0f, 0x61, - 0x2c, 0x20, 0x68, 0x3b, 0x5b, 0xcc, 0xa3, 0x77, 0x76, 0x6e, 0x24, 0x6f, 0xf6, 0x82, 0x1b, 0xf2, - 0x74, 0x35, 0xb9, 0xef, 0xc1, 0x9f, 0xb7, 0x42, 0xc7, 0xdc, 0xf8, 0x0c, 0xc1, 0x84, 0x04, 0x0c, - 0xa7, 0xab, 0xd3, 0xc5, 0xc0, 0x29, 0x18, 0xb2, 0x5c, 0x4a, 0x04, 0x73, 0xa5, 0xf3, 0xc3, 0x05, - 0x7f, 0x89, 0xa7, 0x61, 0x58, 0xaa, 0x54, 0x09, 0xaf, 0xa6, 0xce, 0xca, 0xb3, 0x73, 0xde, 0xc6, - 0x3d, 0xc2, 0xab, 0x78, 0x0a, 0x06, 0x39, 0x6b, 0xb8, 0x16, 0x4d, 0x25, 0xe5, 0x89, 0x5e, 0x79, - 0xe6, 0x4a, 0x0d, 0xbb, 0x56, 0xa6, 0x6e, 0x6a, 0x40, 0x99, 0xd3, 0x4b, 0x63, 0x17, 0x2e, 0xe8, - 0xb0, 0x94, 0x69, 0x40, 0xeb, 0x6d, 0x8d, 0xe1, 0x45, 0x41, 0x12, 0x1b, 0xc9, 0xcf, 0x75, 0x0e, - 0x42, 0xd4, 0xa7, 0x50, 0x02, 0x24, 0x2f, 0xef, 0xcc, 0xbb, 0xc8, 0x3b, 0x84, 0x6f, 0xeb, 0x67, - 0x2a, 0xbf, 0x0d, 0x0b, 0x70, 0x80, 0xcc, 0x03, 0xe8, 0x37, 0x01, 0x02, 0x68, 0x3f, 0x01, 0xbd, - 0x63, 0xab, 0xc8, 0x0f, 0xfb, 0xb8, 0xdc, 0xd8, 0x80, 0x2b, 0x91, 0xac, 0x07, 0x6f, 0xbb, 0xef, - 0xf7, 0x62, 0xe4, 0x75, 0xd1, 0xf2, 0x4d, 0xe9, 0xda, 0xa2, 0x0d, 0xc5, 0x17, 0x97, 0x65, 0xb8, - 0x18, 0xf8, 0xe8, 0x25, 0x28, 0x10, 0x8f, 0x64, 0x11, 0x45, 0xb3, 0x68, 0x7c, 0x8e, 0x60, 0xfc, - 0x2e, 0xb5, 0xdc, 0x66, 0x5d, 0xd0, 0xf2, 0x8a, 0xc3, 0x77, 0xa8, 0xeb, 0x45, 0xd0, 0xab, 0xe6, - 0x5a, 0x56, 0x7e, 0x7b, 0x98, 0xb6, 0x53, 0x6f, 0x08, 0x7d, 0x45, 0xd4, 0x02, 0xcf, 0xc0, 0x08, - 0x6b, 0x88, 0x7a, 0x43, 0x14, 0x65, 0xed, 0x50, 0x57, 0x04, 0xd4, 0xd6, 0x5d, 0x22, 0x08, 0xce, - 0xc1, 0xc5, 0x90, 0x40, 0x91, 0xf0, 0x22, 0x17, 0xae, 0xed, 0x54, 0xf4, 0x9d, 0xc1, 0xc7, 0xa2, - 0x2b, 0xfc, 0x81, 0x3c, 0xb9, 0x93, 0xfc, 0xeb, 0x9b, 0x99, 0x84, 0xf1, 0x0f, 0x82, 0x89, 0x16, - 0x5e, 0x1c, 0xaf, 0xc0, 0x10, 0x51, 0x9f, 0x3a, 0x5b, 0xb3, 0x9d, 0xb2, 0xd5, 0xa2, 0x5a, 0xf0, - 0xf5, 0xf0, 0x66, 0xc0, 0xb8, 0xc6, 0x2a, 0x3c, 0x75, 0x46, 0x9a, 0x79, 0x31, 0xab, 0x1a, 0x4a, - 0xd6, 0x6b, 0x28, 0x59, 0xd9, 0x68, 0x7c, 0x43, 0x8a, 0xd4, 0xfa, 0x13, 0xea, 0x08, 0x9d, 0x71, - 0xed, 0xde, 0x26, 0xab, 0x70, 0x7c, 0x0d, 0x46, 0xb5, 0x35, 0xea, 0xba, 0xcc, 0xd5, 0x01, 0xd0, - 0x08, 0xeb, 0xde, 0x16, 0x9e, 0x85, 0xf1, 0x7a, 0x8d, 0xd8, 0x8e, 0xa0, 0xbb, 0xbe, 0x94, 0xf2, - 0x7d, 0x2c, 0xd8, 0x96, 0x82, 0xda, 0xef, 0x2f, 0x90, 0x2e, 0xd3, 0x7e, 0xea, 0xef, 0xd9, 0x5c, - 0x30, 0xb7, 0x79, 0x8a, 0x86, 0xf5, 0x1a, 0xc0, 0x71, 0x37, 0xd4, 0x75, 0xed, 0x46, 0xc4, 0x53, - 0x35, 0x05, 0xf8, 0xae, 0xde, 0x27, 0x15, 0xaa, 0x61, 0x0a, 0x21, 0x4d, 0x4d, 0xec, 0x67, 0xd4, - 0x72, 0xbd, 0x03, 0x62, 0xfa, 0x9a, 0xdd, 0x87, 0x21, 0xea, 0x08, 0xd7, 0xa6, 0x7e, 0x72, 0x6e, - 0x75, 0xab, 0x65, 0xf2, 0xa6, 0x2a, 0x2b, 0xeb, 0x8e, 0x70, 0x9b, 0x3a, 0xc0, 0xbe, 0x19, 0xfc, - 0x7a, 0x8c, 0x03, 0xb3, 0x5d, 0x1d, 0x50, 0x74, 0xda, 0x3d, 0xc8, 0x7f, 0x7d, 0x1e, 0x06, 0xa4, - 0x07, 0xf8, 0x7b, 0x14, 0x2d, 0xfa, 0xf8, 0xe5, 0x4e, 0x54, 0x4f, 0x6c, 0xd7, 0xe9, 0xdc, 0x89, - 0x6a, 0x71, 0x4d, 0xd3, 0xb8, 0xf5, 0xd1, 0xaf, 0x7f, 0x7e, 0x7a, 0x66, 0x01, 0xcf, 0xb5, 0x0d, - 0x50, 0x5e, 0x15, 0x32, 0x3f, 0x68, 0x4d, 0xee, 0x1e, 0xfe, 0x0e, 0xc1, 0x85, 0xb6, 0x46, 0x82, - 0x6f, 0x76, 0x65, 0x1c, 0x1a, 0x0a, 0xd2, 0xb7, 0x7b, 0x22, 0xda, 0xd6, 0xa6, 0x8c, 0x9b, 0x92, - 0xed, 0x0d, 0x7c, 0xbd, 0x8d, 0xad, 0xcf, 0x93, 0x7b, 0x94, 0x65, 0x57, 0xd9, 0xc3, 0x3f, 0x22, - 0x3d, 0x0c, 0x45, 0x47, 0x0c, 0x9c, 0x3f, 0x11, 0x3d, 0x76, 0x30, 0x4b, 0x2f, 0xf5, 0xa5, 0xa3, - 0xe9, 0xe6, 0x24, 0xdd, 0x45, 0x3c, 0x1f, 0x3f, 0xef, 0xc6, 0x45, 0xf7, 0x63, 0x04, 0x49, 0xcf, - 0xe9, 0x3e, 0x03, 0x3a, 0xdf, 0x25, 0xa0, 0xc7, 0x0d, 0xce, 0x98, 0x95, 0xa4, 0xae, 0xe1, 0x99, - 0x98, 0x18, 0x96, 0x69, 0x28, 0x7c, 0x8f, 0x60, 0x40, 0xf6, 0x27, 0x3c, 0x95, 0x55, 0x23, 0x72, - 0xd6, 0x9f, 0x9f, 0xb3, 0xeb, 0xde, 0xfc, 0x9c, 0x5e, 0xe8, 0x0a, 0x1a, 0x34, 0x1b, 0x23, 0x23, - 0x51, 0x53, 0x78, 0x2a, 0x16, 0x95, 0xe3, 0x5f, 0x10, 0x5c, 0xf6, 0x3b, 0x45, 0xdb, 0xfd, 0x3e, - 0xed, 0x7b, 0x78, 0xa9, 0x2b, 0xc1, 0x70, 0x63, 0x32, 0x36, 0x24, 0xc7, 0x35, 0xbc, 0x12, 0xcb, - 0x51, 0xf6, 0x2b, 0xb3, 0xd4, 0x2c, 0xb6, 0x26, 0x2d, 0x2e, 0x8d, 0x4f, 0xf5, 0xc4, 0xe3, 0xbb, - 0x73, 0x8a, 0x37, 0xd2, 0x27, 0xf9, 0x57, 0x24, 0xf9, 0x1c, 0x36, 0xbb, 0x91, 0x97, 0xd9, 0x0d, - 0xa5, 0xf9, 0x07, 0x04, 0x63, 0xb2, 0x9f, 0xaf, 0x36, 0xff, 0x63, 0xb8, 0xf3, 0x3d, 0xbd, 0xea, - 0xc8, 0xec, 0x70, 0xc2, 0x13, 0x91, 0x53, 0x44, 0x5c, 0x6c, 0xbf, 0x45, 0x30, 0xe6, 0x8f, 0x9b, - 0xea, 0x2f, 0x07, 0x2f, 0x76, 0x21, 0x1c, 0xfe, 0x17, 0x4a, 0x2f, 0xf7, 0x44, 0xb3, 0x65, 0x5a, - 0x3a, 0x81, 0x68, 0xfb, 0x7d, 0x90, 0xd4, 0xf7, 0xf0, 0x4f, 0x08, 0xc6, 0x5b, 0xba, 0x13, 0x5e, - 0xea, 0x09, 0x3c, 0xda, 0x64, 0x7b, 0x64, 0xdc, 0xd2, 0x00, 0x8d, 0x57, 0x25, 0xe3, 0xdb, 0x78, - 0xb9, 0x33, 0xe3, 0xaa, 0x52, 0x89, 0x89, 0xf2, 0xea, 0xc3, 0xfd, 0x3f, 0x32, 0x89, 0xa7, 0x87, - 0x19, 0xb4, 0x7f, 0x98, 0x41, 0x07, 0x87, 0x19, 0xf4, 0xfb, 0x61, 0x06, 0x7d, 0x72, 0x94, 0x49, - 0x1c, 0x1c, 0x65, 0x12, 0xbf, 0x1d, 0x65, 0x12, 0xef, 0xdd, 0xa9, 0xd8, 0xa2, 0xda, 0x28, 0x79, - 0xa4, 0x4c, 0x6e, 0xb9, 0xa2, 0x46, 0x4a, 0xdc, 0x54, 0x95, 0xf0, 0x2d, 0x2a, 0x76, 0x98, 0xfb, - 0xc8, 0xdc, 0x0d, 0xa0, 0xbd, 0xc9, 0xc2, 0x75, 0x48, 0x4d, 0xfd, 0x97, 0x97, 0x06, 0x65, 0x29, - 0x59, 0xfa, 0x37, 0x00, 0x00, 0xff, 0xff, 0x95, 0x99, 0xf7, 0x6a, 0x10, 0x10, 0x00, 0x00, + // 1245 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x57, 0xcf, 0x6f, 0x1b, 0xc5, + 0x17, 0xf7, 0xb4, 0x4e, 0xd3, 0x4c, 0xd2, 0x24, 0x9d, 0x6f, 0x9a, 0xba, 0x4e, 0xbf, 0x4e, 0xbb, + 0x14, 0xf2, 0xab, 0x78, 0x6b, 0x27, 0x14, 0xa9, 0xe2, 0x92, 0xa4, 0x91, 0x1a, 0x14, 0x0a, 0xb8, + 0x07, 0x24, 0x54, 0x64, 0x8d, 0xd7, 0x13, 0x7b, 0x55, 0x67, 0xc7, 0xdd, 0x19, 0x27, 0xb1, 0x50, + 0x38, 0x70, 0xe2, 0x88, 0x04, 0x48, 0x08, 0x2e, 0x9c, 0xa0, 0xe2, 0x80, 0xc4, 0x95, 0xbf, 0x20, + 0x07, 0x0e, 0x91, 0xb8, 0x70, 0xaa, 0x20, 0xe1, 0x80, 0xb8, 0x73, 0x47, 0xf3, 0x66, 0x76, 0xb3, + 0xb6, 0xd7, 0xb1, 0x5d, 0x0e, 0xdc, 0x76, 0x66, 0xde, 0xbc, 0xcf, 0x67, 0x3e, 0xef, 0xcd, 0x7b, + 0xb3, 0xd8, 0x12, 0xcc, 0xf1, 0x99, 0xb4, 0x1d, 0xbe, 0x53, 0x6f, 0x48, 0x66, 0xef, 0xe6, 0x4a, + 0x4c, 0xd2, 0x9c, 0xfd, 0xb4, 0xc1, 0xfc, 0x66, 0xb6, 0xee, 0x73, 0xc9, 0xc9, 0xb4, 0xb6, 0xc9, + 0x1a, 0x9b, 0xac, 0xb1, 0x49, 0x4f, 0x55, 0x78, 0x85, 0x83, 0x89, 0xad, 0xbe, 0xb4, 0x75, 0xba, + 0x9b, 0x47, 0xd9, 0xac, 0x33, 0x61, 0x6c, 0x66, 0x2a, 0x9c, 0x57, 0x6a, 0xcc, 0x86, 0x51, 0xa9, + 0xb1, 0x6d, 0xb3, 0x9d, 0xba, 0x34, 0x70, 0xe9, 0xeb, 0x66, 0x91, 0xd6, 0x5d, 0x9b, 0x7a, 0x1e, + 0x97, 0x54, 0xba, 0xdc, 0x0b, 0xb6, 0xbe, 0xe4, 0x70, 0xb1, 0xc3, 0x85, 0x5d, 0xa2, 0x82, 0xd9, + 0xb4, 0xe4, 0xb8, 0x21, 0x80, 0x1a, 0x18, 0xa3, 0xc5, 0xa8, 0x11, 0x1c, 0x25, 0xb4, 0xaa, 0xd3, + 0x8a, 0xeb, 0x81, 0x47, 0x6d, 0x6b, 0x7d, 0x80, 0xd3, 0xef, 0x2a, 0x8b, 0x47, 0x40, 0x7b, 0x9d, + 0x7b, 0xd2, 0xa7, 0x8e, 0x2c, 0xb0, 0xa7, 0x0d, 0x26, 0x24, 0x59, 0xc0, 0x93, 0x8e, 0x99, 0x2a, + 0xd2, 0x72, 0xd9, 0x67, 0x42, 0xa4, 0xd0, 0x0d, 0x34, 0x3f, 0x52, 0x98, 0x08, 0xe6, 0x57, 0xf5, + 0x34, 0x99, 0xc2, 0x43, 0x00, 0x95, 0x3a, 0x77, 0x03, 0xcd, 0x8f, 0x15, 0xf4, 0xc0, 0x5a, 0xc2, + 0xff, 0x03, 0xf7, 0x6b, 0xcd, 0x2d, 0x5a, 0x62, 0xb5, 0xc0, 0xef, 0x14, 0x1e, 0xaa, 0xa9, 0xb1, + 0x71, 0xa6, 0x07, 0xd6, 0x9b, 0xf8, 0xff, 0xc6, 0x78, 0xbd, 0xd5, 0xf9, 0xe0, 0x74, 0x2c, 0x1b, + 0x4f, 0x85, 0xbe, 0xca, 0x6c, 0xb3, 0x1c, 0xb8, 0xb8, 0x8a, 0x87, 0x1d, 0x5e, 0x66, 0x45, 0xb7, + 0x0c, 0x3b, 0x93, 0x85, 0x0b, 0x0e, 0xac, 0x5b, 0x39, 0x3c, 0x13, 0x2b, 0x84, 0xa8, 0x73, 0x4f, + 0x30, 0x42, 0x70, 0xb2, 0x4c, 0x25, 0x85, 0x4d, 0x63, 0x05, 0xf8, 0xb6, 0xbe, 0x42, 0xf8, 0x1a, + 0xec, 0x09, 0xac, 0x37, 0xbd, 0x6d, 0x1e, 0xee, 0x18, 0x40, 0xbb, 0x02, 0x1e, 0x8b, 0xba, 0x00, + 0x09, 0x47, 0xf3, 0xb7, 0xb2, 0xf1, 0x99, 0x97, 0x8d, 0xda, 0xae, 0x5d, 0x3c, 0x7a, 0x3e, 0x8b, + 0xfe, 0x7a, 0x3e, 0x9b, 0x28, 0xb4, 0xf8, 0xb0, 0xbe, 0x44, 0xf8, 0x6a, 0x74, 0xe2, 0x3d, 0x57, + 0x56, 0x03, 0xbc, 0xff, 0x98, 0xda, 0x47, 0x38, 0xd3, 0x22, 0x9b, 0x38, 0x0d, 0x92, 0xd1, 0xee, + 0x31, 0x1e, 0x0f, 0x09, 0xba, 0xde, 0x36, 0x57, 0xf4, 0xce, 0xcf, 0x8f, 0xe6, 0xed, 0x7e, 0x70, + 0x23, 0x27, 0x5d, 0x4b, 0x1e, 0x2a, 0xf8, 0x4b, 0x4e, 0x64, 0x59, 0x58, 0x9f, 0x23, 0x3c, 0x09, + 0x80, 0xd1, 0x70, 0x75, 0x4b, 0x0c, 0x92, 0xc2, 0xc3, 0x8e, 0xcf, 0xa8, 0xe4, 0x3e, 0x1c, 0x7e, + 0xa4, 0x10, 0x0c, 0xc9, 0x0c, 0x1e, 0x81, 0x2d, 0x55, 0x2a, 0xaa, 0xa9, 0xf3, 0xb0, 0x76, 0x51, + 0x4d, 0x3c, 0xa0, 0xa2, 0x4a, 0xa6, 0xf1, 0x05, 0xc1, 0x1b, 0xbe, 0xc3, 0x52, 0x49, 0x58, 0x31, + 0x23, 0xe5, 0xae, 0xd4, 0x70, 0x6b, 0x65, 0xe6, 0xa7, 0x86, 0xb4, 0x3b, 0x33, 0xb4, 0xf6, 0xf1, + 0x65, 0x23, 0x4b, 0x99, 0x85, 0xb4, 0xde, 0x36, 0x18, 0x4a, 0x05, 0x20, 0x36, 0x9a, 0x9f, 0xef, + 0x2e, 0x42, 0xeb, 0x99, 0x22, 0x01, 0x00, 0x5e, 0x6a, 0x4d, 0x25, 0xf2, 0x1e, 0x15, 0x3b, 0xe6, + 0x9a, 0xc2, 0xb7, 0xe5, 0x60, 0x12, 0x22, 0x8b, 0x10, 0xfa, 0x2d, 0x8c, 0x43, 0xe8, 0x20, 0x00, + 0xfd, 0x63, 0x6b, 0xe5, 0x47, 0x02, 0x5c, 0x61, 0x6d, 0xe2, 0xeb, 0x2d, 0x51, 0x0f, 0xef, 0xf6, + 0xc0, 0xf7, 0xc5, 0xca, 0x9b, 0xa2, 0x15, 0xb8, 0x32, 0xb5, 0xc5, 0x38, 0x8a, 0x2f, 0x2e, 0x2b, + 0xf8, 0x4a, 0x78, 0x46, 0x15, 0xa0, 0xd0, 0xbc, 0x25, 0x8a, 0xa8, 0x35, 0x8a, 0xd6, 0x17, 0x08, + 0x4f, 0xdc, 0x67, 0x8e, 0xdf, 0xac, 0x4b, 0x56, 0x5e, 0xf5, 0xc4, 0x1e, 0xf3, 0x95, 0x82, 0xaa, + 0x9a, 0x1b, 0x5b, 0xf8, 0x56, 0x98, 0xae, 0x57, 0x6f, 0x48, 0x93, 0x22, 0x7a, 0x40, 0x66, 0xf1, + 0x28, 0x6f, 0xc8, 0x7a, 0x43, 0x16, 0xa1, 0x76, 0xe8, 0x14, 0xc1, 0x7a, 0xea, 0x3e, 0x95, 0x94, + 0xe4, 0xf0, 0x95, 0x88, 0x41, 0x91, 0x8a, 0xa2, 0x90, 0xbe, 0xeb, 0x55, 0x4c, 0xce, 0x90, 0x53, + 0xd3, 0x55, 0xf1, 0x08, 0x56, 0xee, 0x25, 0xff, 0xfc, 0x66, 0x36, 0x61, 0xfd, 0x8d, 0xf0, 0x64, + 0x1b, 0x2f, 0x41, 0x56, 0xf1, 0x30, 0xd5, 0x9f, 0x26, 0x5a, 0x73, 0xdd, 0xa2, 0xd5, 0xb6, 0xb5, + 0x10, 0xec, 0x23, 0x5b, 0x21, 0xe3, 0x1a, 0xaf, 0x88, 0xd4, 0x39, 0x70, 0xf3, 0x72, 0x56, 0x37, + 0x94, 0xac, 0x6a, 0x28, 0x59, 0x68, 0x34, 0x81, 0x23, 0x4d, 0x6a, 0x63, 0x97, 0x79, 0xd2, 0x44, + 0xdc, 0x1c, 0x6f, 0x8b, 0x57, 0x04, 0xb9, 0x89, 0xc7, 0x8c, 0x37, 0xe6, 0xfb, 0xdc, 0x37, 0x02, + 0x18, 0x84, 0x0d, 0x35, 0x45, 0xe6, 0xf0, 0x44, 0xbd, 0x46, 0x5d, 0x4f, 0xb2, 0xfd, 0xc0, 0x4a, + 0x9f, 0x7d, 0x3c, 0x9c, 0x06, 0x43, 0x73, 0xee, 0x87, 0xa6, 0x4a, 0x07, 0x91, 0x7f, 0xe0, 0x0a, + 0xc9, 0xfd, 0xe6, 0xe0, 0x0d, 0xc2, 0xf8, 0xdb, 0x6d, 0x4b, 0xca, 0xd0, 0x9f, 0x49, 0x8e, 0x77, + 0xf0, 0x30, 0xf3, 0xa4, 0xef, 0xb2, 0x40, 0xd2, 0x3b, 0xbd, 0x2a, 0x10, 0xe4, 0x97, 0xf6, 0xb2, + 0xe1, 0x49, 0xbf, 0x69, 0x64, 0x09, 0xdc, 0x68, 0xdc, 0xfc, 0xd7, 0x97, 0xf0, 0x10, 0x00, 0x93, + 0xef, 0x51, 0x6b, 0x85, 0x25, 0xaf, 0x75, 0x43, 0x38, 0xb3, 0x37, 0xa6, 0x73, 0x67, 0x6e, 0x8b, + 0xeb, 0x50, 0xd6, 0x9d, 0x8f, 0x7f, 0xf9, 0xe3, 0xb3, 0x73, 0x8b, 0x64, 0xbe, 0xe3, 0xb5, 0xa2, + 0xae, 0xbc, 0xfd, 0x61, 0xbb, 0x94, 0x07, 0xe4, 0x3b, 0x84, 0x2f, 0x77, 0x54, 0x6d, 0x72, 0xbb, + 0x27, 0xe3, 0x48, 0x07, 0x4e, 0xdf, 0xed, 0x8b, 0x68, 0x47, 0x4f, 0xb0, 0x6e, 0x03, 0xdb, 0x57, + 0xc8, 0xad, 0x0e, 0xb6, 0x01, 0x4f, 0xa1, 0x28, 0x43, 0x09, 0x3f, 0x20, 0x3f, 0x22, 0xf3, 0xf2, + 0x68, 0xed, 0xe7, 0x24, 0x7f, 0x26, 0x7a, 0xec, 0x2b, 0x28, 0xbd, 0x3c, 0xd0, 0x1e, 0x43, 0x37, + 0x07, 0x74, 0x97, 0xc8, 0x42, 0xfc, 0xe3, 0x32, 0x4e, 0xdd, 0x4f, 0x10, 0x4e, 0xaa, 0x43, 0x0f, + 0x28, 0xe8, 0x42, 0x0f, 0x41, 0x4f, 0xbb, 0x89, 0x35, 0x07, 0xa4, 0x6e, 0x92, 0xd9, 0x18, 0x0d, + 0xcb, 0x2c, 0x22, 0xdf, 0x13, 0x3c, 0x04, 0xcd, 0x80, 0x4c, 0x67, 0xf5, 0x7b, 0x34, 0x1b, 0x3c, + 0x56, 0xb3, 0x1b, 0xea, 0xb1, 0x9a, 0x5e, 0xec, 0x09, 0x1a, 0x56, 0x76, 0x2b, 0x03, 0xa8, 0x29, + 0x32, 0x1d, 0x8b, 0x2a, 0xc8, 0xcf, 0x08, 0x5f, 0x0b, 0xca, 0x72, 0x47, 0x7e, 0xbf, 0xe8, 0x7d, + 0x78, 0xb5, 0x27, 0xc1, 0x68, 0x17, 0xb0, 0x36, 0x81, 0xe3, 0x3a, 0x59, 0x8d, 0xe5, 0x08, 0xcd, + 0xc1, 0x2e, 0x35, 0x8b, 0xed, 0x41, 0x8b, 0x0b, 0xe3, 0x33, 0xf3, 0xbc, 0x08, 0x8e, 0xf3, 0x02, + 0x77, 0x64, 0x40, 0xf2, 0xaf, 0x03, 0xf9, 0x1c, 0xb1, 0x7b, 0x91, 0x87, 0xe8, 0x46, 0xc2, 0xfc, + 0x03, 0xc2, 0xe3, 0xd0, 0x3c, 0xd7, 0x9a, 0xff, 0x52, 0xee, 0x7c, 0x5f, 0xb7, 0xba, 0xa5, 0x51, + 0x9f, 0x71, 0x45, 0xa0, 0x65, 0xc7, 0x69, 0xfb, 0x2d, 0xc2, 0xe3, 0xc1, 0xdb, 0x4e, 0xff, 0x52, + 0x90, 0xa5, 0x1e, 0x84, 0xa3, 0x3f, 0x1e, 0xe9, 0x95, 0xbe, 0x68, 0xb6, 0x3d, 0x4d, 0xce, 0x20, + 0xda, 0x99, 0x0f, 0x40, 0xfd, 0x80, 0xfc, 0x84, 0xf0, 0x44, 0x5b, 0x53, 0x21, 0xcb, 0x7d, 0x81, + 0xb7, 0xb6, 0xb4, 0x3e, 0x19, 0xb7, 0xf5, 0x2d, 0xeb, 0x0d, 0x60, 0x7c, 0x97, 0xac, 0x74, 0x67, + 0x5c, 0xd5, 0x5b, 0x62, 0x54, 0x5e, 0x7b, 0x7c, 0xf8, 0x7b, 0x26, 0xf1, 0xec, 0x38, 0x83, 0x0e, + 0x8f, 0x33, 0xe8, 0xe8, 0x38, 0x83, 0x7e, 0x3b, 0xce, 0xa0, 0x4f, 0x4f, 0x32, 0x89, 0xa3, 0x93, + 0x4c, 0xe2, 0xd7, 0x93, 0x4c, 0xe2, 0xfd, 0x7b, 0x15, 0x57, 0x56, 0x1b, 0x25, 0x45, 0xca, 0x16, + 0x8e, 0x2f, 0x6b, 0xb4, 0x24, 0x6c, 0x5d, 0x09, 0x1f, 0x32, 0xb9, 0xc7, 0xfd, 0x27, 0xf6, 0x7e, + 0x08, 0xad, 0xda, 0xb8, 0xef, 0xd1, 0x9a, 0xfe, 0x09, 0x2e, 0x5d, 0x80, 0x52, 0xb2, 0xfc, 0x4f, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x58, 0xe3, 0xa9, 0xe7, 0x7d, 0x0f, 0x00, 0x00, } func (this *QuerySecretContractRequest) Equal(that interface{}) bool { @@ -2272,18 +2266,6 @@ func (m *QueryContractHistoryRequest) MarshalToSizedBuffer(dAtA []byte) (int, er _ = i var l int _ = l - if m.Pagination != nil { - { - size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } if len(m.ContractAddress) > 0 { i -= len(m.ContractAddress) copy(dAtA[i:], m.ContractAddress) @@ -2314,18 +2296,6 @@ func (m *QueryContractHistoryResponse) MarshalToSizedBuffer(dAtA []byte) (int, e _ = i var l int _ = l - if m.Pagination != nil { - { - size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } if len(m.Entries) > 0 { for iNdEx := len(m.Entries) - 1; iNdEx >= 0; iNdEx-- { { @@ -2634,10 +2604,6 @@ func (m *QueryContractHistoryRequest) Size() (n int) { if l > 0 { n += 1 + l + sovQuery(uint64(l)) } - if m.Pagination != nil { - l = m.Pagination.Size() - n += 1 + l + sovQuery(uint64(l)) - } return n } @@ -2653,10 +2619,6 @@ func (m *QueryContractHistoryResponse) Size() (n int) { n += 1 + l + sovQuery(uint64(l)) } } - if m.Pagination != nil { - l = m.Pagination.Size() - n += 1 + l + sovQuery(uint64(l)) - } return n } @@ -4487,42 +4449,6 @@ func (m *QueryContractHistoryRequest) Unmarshal(dAtA []byte) error { } m.ContractAddress = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Pagination == nil { - m.Pagination = &query.PageRequest{} - } - if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -4607,42 +4533,6 @@ func (m *QueryContractHistoryResponse) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Pagination == nil { - m.Pagination = &query.PageResponse{} - } - if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) diff --git a/x/compute/internal/types/query.pb.gw.go b/x/compute/internal/types/query.pb.gw.go index 687b5f4f9..a51afbe4c 100644 --- a/x/compute/internal/types/query.pb.gw.go +++ b/x/compute/internal/types/query.pb.gw.go @@ -500,10 +500,6 @@ func local_request_Query_AddressByLabel_0(ctx context.Context, marshaler runtime } -var ( - filter_Query_ContractHistory_0 = &utilities.DoubleArray{Encoding: map[string]int{"contract_address": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} -) - func request_Query_ContractHistory_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq QueryContractHistoryRequest var metadata runtime.ServerMetadata @@ -526,13 +522,6 @@ func request_Query_ContractHistory_0(ctx context.Context, marshaler runtime.Mars return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "contract_address", err) } - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_ContractHistory_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - msg, err := client.ContractHistory(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err @@ -560,13 +549,6 @@ func local_request_Query_ContractHistory_0(ctx context.Context, marshaler runtim return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "contract_address", err) } - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_ContractHistory_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - msg, err := server.ContractHistory(ctx, &protoReq) return msg, metadata, err From 04c33910df87b7ebb1fc18595d84b3ff36cde89a Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 13 Jun 2023 21:25:50 +0300 Subject: [PATCH 026/164] Fix null admin --- go-cosmwasm/src/lib.rs | 2 +- x/compute/internal/keeper/keeper.go | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/go-cosmwasm/src/lib.rs b/go-cosmwasm/src/lib.rs index fb2cb4d35..2bc9200c3 100644 --- a/go-cosmwasm/src/lib.rs +++ b/go-cosmwasm/src/lib.rs @@ -490,7 +490,7 @@ fn do_init( let params = unsafe { params.read() }.ok_or_else(|| Error::empty_arg(PARAMS_ARG))?; let msg = unsafe { msg.read() }.ok_or_else(|| Error::empty_arg(MSG_ARG))?; let sig_info = unsafe { sig_info.read() }.ok_or_else(|| Error::empty_arg(SIG_INFO_ARG))?; - let admin = unsafe { admin.read() }.ok_or_else(|| Error::empty_arg(ADMIN_ARG))?; + let admin = unsafe { admin.read() }.unwrap_or_default(); let deps = to_extern(db, api, querier); let mut instance = cache.get_instance(&code_id, deps, gas_limit)?; diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index 5285c4139..30de26ffa 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -440,10 +440,6 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator sdk.AccAddre return nil, nil, sdkerrors.Wrap(types.ErrAccountExists, existingAcct.GetAddress().String()) } - if admin == nil { - admin = creator - } - // deposit initial contract funds if !deposit.IsZero() { if k.bankKeeper.BlockedAddr(creator) { From 26acec75a8d338d3232b602edd0b8fbbab20c4f9 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 13 Jun 2023 21:26:14 +0300 Subject: [PATCH 027/164] Fix null admin Amino parsing inside the enclave --- cosmwasm/enclaves/shared/cosmos-types/src/types.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs index 7dfa805c8..2eea11dee 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs @@ -310,6 +310,7 @@ pub enum AminoSdkMsg { init_funds: Vec, label: String, callback_sig: Option>, + #[serde(default)] admin: HumanAddr, }, #[serde(alias = "wasm/MsgMigrateContract")] From 61e98eaaee3c87c988ebcab13203061dc6417ce2 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 13 Jun 2023 21:27:09 +0300 Subject: [PATCH 028/164] Fix contractHistory query from CLI --- x/compute/client/cli/query.go | 5 ----- x/compute/internal/keeper/querier.go | 3 --- 2 files changed, 8 deletions(-) diff --git a/x/compute/client/cli/query.go b/x/compute/client/cli/query.go index 70f43472e..fae6b7d50 100644 --- a/x/compute/client/cli/query.go +++ b/x/compute/client/cli/query.go @@ -733,16 +733,11 @@ func GetCmdGetContractHistory() *cobra.Command { return err } - pageReq, err := client.ReadPageRequest(withPageKeyDecoded(cmd.Flags())) - if err != nil { - return err - } queryClient := types.NewQueryClient(clientCtx) res, err := queryClient.ContractHistory( context.Background(), &types.QueryContractHistoryRequest{ ContractAddress: args[0], - Pagination: pageReq, }, ) if err != nil { diff --git a/x/compute/internal/keeper/querier.go b/x/compute/internal/keeper/querier.go index d1739b844..a5191b7f7 100644 --- a/x/compute/internal/keeper/querier.go +++ b/x/compute/internal/keeper/querier.go @@ -201,9 +201,6 @@ func queryContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress, keeper K return nil, nil } - // redact the Created field (just used for sorting, not part of public API) - info.Created = nil - return &types.ContractInfoWithAddress{ ContractAddress: contractAddress.String(), ContractInfo: info, From da0aae27436dd1e47d3d4038942f96d900e3ea03 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 13 Jun 2023 21:29:56 +0300 Subject: [PATCH 029/164] Add admin param to init tests --- x/compute/internal/keeper/bench_test.go | 2 +- .../internal/keeper/distribution_test.go | 2 +- x/compute/internal/keeper/gov_test.go | 4 +- x/compute/internal/keeper/ibc_test.go | 22 +-- x/compute/internal/keeper/keeper.go | 2 +- x/compute/internal/keeper/keeper_test.go | 10 +- x/compute/internal/keeper/mint_test.go | 2 +- .../keeper/param_verification_test.go | 14 +- x/compute/internal/keeper/querier_test.go | 2 +- x/compute/internal/keeper/recurse_test.go | 2 +- .../keeper/secret_contracts_exec_test.go | 131 +++++++++--------- .../keeper/secret_contracts_init_test.go | 120 ++++++++-------- .../keeper/secret_contracts_migrate_test.go | 6 +- .../keeper/secret_contracts_query_test.go | 62 ++++----- .../keeper/secret_contracts_submsgs_test.go | 56 ++++---- .../keeper/secret_contracts_utils_test.go | 10 +- .../keeper/secret_contracts_v010_test.go | 14 +- .../keeper/secret_contracts_v1_v010_test.go | 80 +++++------ x/compute/internal/keeper/staking_test.go | 6 +- x/compute/internal/keeper/test_common.go | 4 +- 20 files changed, 275 insertions(+), 276 deletions(-) diff --git a/x/compute/internal/keeper/bench_test.go b/x/compute/internal/keeper/bench_test.go index 8e1ceb133..be54ab0c6 100644 --- a/x/compute/internal/keeper/bench_test.go +++ b/x/compute/internal/keeper/bench_test.go @@ -163,7 +163,7 @@ func initBenchContract(t *testing.T) (contract sdk.AccAddress, creator sdk.AccAd codeID, err := keeper.Create(ctx, creator, wasmCode, "", "") require.NoError(t, err) - _, _, contractAddr, _, initErr := initHelper(t, keeper, ctx, codeID, creator, creatorPriv, `{"init": {}}`, true, true, defaultGasForTests) + _, _, contractAddr, _, initErr := initHelper(t, keeper, ctx, codeID, creator, nil, creatorPriv, `{"init": {}}`, true, true, defaultGasForTests) require.Empty(t, initErr) return contractAddr, creator, creatorPriv, ctx, keeper diff --git a/x/compute/internal/keeper/distribution_test.go b/x/compute/internal/keeper/distribution_test.go index aaa8627fa..c532b9fb7 100644 --- a/x/compute/internal/keeper/distribution_test.go +++ b/x/compute/internal/keeper/distribution_test.go @@ -79,7 +79,7 @@ func TestDistributionRewards(t *testing.T) { initBz, err = testEncrypt(t, keeper, ctx, nil, govId, initBz) require.NoError(t, err) - ctx = PrepareInitSignedTx(t, keeper, ctx, creator, creatorPrivKey, initBz, govId, nil) + ctx = PrepareInitSignedTx(t, keeper, ctx, creator, nil, creatorPrivKey, initBz, govId, nil) govAddr, _, err := keeper.Instantiate(ctx, govId, creator, creator, initBz, "gidi gov", nil, nil) require.NoError(t, err) require.NotEmpty(t, govAddr) diff --git a/x/compute/internal/keeper/gov_test.go b/x/compute/internal/keeper/gov_test.go index de2619ebb..c736b6164 100644 --- a/x/compute/internal/keeper/gov_test.go +++ b/x/compute/internal/keeper/gov_test.go @@ -68,7 +68,7 @@ func TestGovQueryProposals(t *testing.T) { initBz, err = testEncrypt(t, keeper, ctx, nil, govId, initBz) require.NoError(t, err) - ctx = PrepareInitSignedTx(t, keeper, ctx, creator, creatorPrivKey, initBz, govId, nil) + ctx = PrepareInitSignedTx(t, keeper, ctx, creator, nil, creatorPrivKey, initBz, govId, nil) govAddr, _, err := keeper.Instantiate(ctx, govId, creator, nil, initBz, "gidi gov", nil, nil) require.NoError(t, err) require.NotEmpty(t, govAddr) @@ -136,7 +136,7 @@ func TestGovVote(t *testing.T) { initBz, err = testEncrypt(t, keeper, ctx, nil, govId, initBz) require.NoError(t, err) - ctx = PrepareInitSignedTx(t, keeper, ctx, creator, creatorPrivKey, initBz, govId, deposit2) + ctx = PrepareInitSignedTx(t, keeper, ctx, creator, nil, creatorPrivKey, initBz, govId, deposit2) govAddr, _, err := keeper.Instantiate(ctx, govId, creator, nil, initBz, "gidi gov", deposit2, nil) require.NoError(t, err) require.NotEmpty(t, govAddr) diff --git a/x/compute/internal/keeper/ibc_test.go b/x/compute/internal/keeper/ibc_test.go index 5f2cc099b..07398befb 100644 --- a/x/compute/internal/keeper/ibc_test.go +++ b/x/compute/internal/keeper/ibc_test.go @@ -492,7 +492,7 @@ func ibcPacketTimeoutHelper( func TestIBCChannelOpen(t *testing.T) { ctx, keeper, codeID, _, walletA, privkeyA, _, _ := setupTest(t, TestContractPaths[ibcContract], sdk.NewCoins()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privkeyA, `{"init":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privkeyA, `{"init":{}}`, true, true, defaultGasForTests) require.Empty(t, err) ibcChannel := v1types.IBCChannel{ @@ -516,7 +516,7 @@ func TestIBCChannelOpen(t *testing.T) { func TestIBCChannelOpenTry(t *testing.T) { ctx, keeper, codeID, _, walletA, privkeyA, _, _ := setupTest(t, TestContractPaths[ibcContract], sdk.NewCoins()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privkeyA, `{"init":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privkeyA, `{"init":{}}`, true, true, defaultGasForTests) require.Empty(t, err) ibcChannel := v1types.IBCChannel{ @@ -540,7 +540,7 @@ func TestIBCChannelOpenTry(t *testing.T) { func TestIBCChannelConnect(t *testing.T) { ctx, keeper, codeID, _, walletA, privkeyA, _, _ := setupTest(t, TestContractPaths[ibcContract], sdk.NewCoins()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privkeyA, `{"init":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privkeyA, `{"init":{}}`, true, true, defaultGasForTests) require.Empty(t, err) for _, test := range []struct { @@ -664,7 +664,7 @@ func TestIBCChannelConnect(t *testing.T) { func TestIBCChannelConnectOpenAck(t *testing.T) { ctx, keeper, codeID, _, walletA, privkeyA, _, _ := setupTest(t, TestContractPaths[ibcContract], sdk.NewCoins()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privkeyA, `{"init":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privkeyA, `{"init":{}}`, true, true, defaultGasForTests) require.Empty(t, err) ibcChannel := v1types.IBCChannel{ @@ -687,7 +687,7 @@ func TestIBCChannelConnectOpenAck(t *testing.T) { func TestIBCChannelClose(t *testing.T) { ctx, keeper, codeID, _, walletA, privkeyA, _, _ := setupTest(t, TestContractPaths[ibcContract], sdk.NewCoins()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privkeyA, `{"init":{}}`, true, true, defaultGasForIbcTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privkeyA, `{"init":{}}`, true, true, defaultGasForIbcTests) require.Empty(t, err) for _, test := range []struct { @@ -811,7 +811,7 @@ func TestIBCChannelClose(t *testing.T) { func TestIBCChannelCloseInit(t *testing.T) { ctx, keeper, codeID, _, walletA, privkeyA, _, _ := setupTest(t, TestContractPaths[ibcContract], sdk.NewCoins()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privkeyA, `{"init":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privkeyA, `{"init":{}}`, true, true, defaultGasForTests) require.Empty(t, err) ibcChannel := v1types.IBCChannel{ @@ -834,7 +834,7 @@ func TestIBCChannelCloseInit(t *testing.T) { func TestIBCPacketReceive(t *testing.T) { ctx, keeper, codeID, _, walletA, privkeyA, _, _ := setupTest(t, TestContractPaths[ibcContract], sdk.NewCoins()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privkeyA, `{"init":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privkeyA, `{"init":{}}`, true, true, defaultGasForTests) require.Empty(t, err) for _, isEncrypted := range []bool{false, true} { for _, test := range []struct { @@ -981,9 +981,9 @@ func TestIBCPacketReceiveCallsV010Contract(t *testing.T) { require.NoError(t, err) v010CodeHash := hex.EncodeToString(codeInfo.CodeHash) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privkeyA, `{"init":{}}`, true, true, defaultGasForIbcTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privkeyA, `{"init":{}}`, true, true, defaultGasForIbcTests) require.Empty(t, err) - _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, privkeyA, `{"counter":{"counter":10}}`, true, false, defaultGasForIbcTests) + _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, nil, privkeyA, `{"counter":{"counter":10}}`, true, false, defaultGasForIbcTests) require.Empty(t, err) contractInfo := ContractInfo{ Address: v010ContractAddress.String(), @@ -1028,7 +1028,7 @@ func TestIBCPacketReceiveCallsV010Contract(t *testing.T) { func TestIBCPacketAck(t *testing.T) { ctx, keeper, codeID, _, walletA, privkeyA, _, _ := setupTest(t, TestContractPaths[ibcContract], sdk.NewCoins()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privkeyA, `{"init":{}}`, true, true, defaultGasForIbcTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privkeyA, `{"init":{}}`, true, true, defaultGasForIbcTests) require.Empty(t, err) for _, test := range []struct { @@ -1153,7 +1153,7 @@ func TestIBCPacketAck(t *testing.T) { func TestIBCPacketTimeout(t *testing.T) { ctx, keeper, codeID, _, walletA, privkeyA, _, _ := setupTest(t, TestContractPaths[ibcContract], sdk.NewCoins()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privkeyA, `{"init":{}}`, true, true, defaultGasForIbcTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privkeyA, `{"init":{}}`, true, true, defaultGasForIbcTests) require.Empty(t, err) for _, test := range []struct { diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index 30de26ffa..b371abdcf 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -403,7 +403,7 @@ func V010MsgsToV1SubMsgs(contractAddr string, msgs []v010wasmTypes.CosmosMsg) ([ } // Instantiate creates an instance of a WASM contract -func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator sdk.AccAddress, admin sdk.AccAddress, initMsg []byte, label string, deposit sdk.Coins, callbackSig []byte) (sdk.AccAddress, []byte, error) { +func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.AccAddress, initMsg []byte, label string, deposit sdk.Coins, callbackSig []byte) (sdk.AccAddress, []byte, error) { defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "instantiate") ctx.GasMeter().ConsumeGas(types.InstanceCost, "Loading CosmWasm module: init") diff --git a/x/compute/internal/keeper/keeper_test.go b/x/compute/internal/keeper/keeper_test.go index 975bb126a..6722d5b9f 100644 --- a/x/compute/internal/keeper/keeper_test.go +++ b/x/compute/internal/keeper/keeper_test.go @@ -356,7 +356,7 @@ func TestInstantiateWithDeposit(t *testing.T) { } // when - _, _, addr, _, err := initHelperImpl(t, keeper, ctx, codeID, bob, bobPriv, string(initMsgBz), false, false, defaultGasForTests, wasmCalls, sdk.NewCoins(sdk.NewInt64Coin("denom", int64(deposit)))) + _, _, addr, _, err := initHelperImpl(t, keeper, ctx, codeID, bob, nil, bobPriv, string(initMsgBz), false, false, defaultGasForTests, wasmCalls, sdk.NewCoins(sdk.NewInt64Coin("denom", int64(deposit)))) // then if spec.expError { require.Error(t, err) @@ -457,7 +457,7 @@ func TestExecute(t *testing.T) { gasBefore := ctx.GasMeter().GasConsumed() - ctx = PrepareInitSignedTx(t, keeper, ctx, creator, creatorPrivKey, initMsgBz, contractID, deposit) + ctx = PrepareInitSignedTx(t, keeper, ctx, creator, nil, creatorPrivKey, initMsgBz, contractID, deposit) // create with no balance is also legal addr, _, err := keeper.Instantiate(ctx, contractID, creator, nil, initMsgBz, "demo contract 1", deposit, nil) @@ -582,7 +582,7 @@ func TestExecuteWithDeposit(t *testing.T) { initMsgBz, err := json.Marshal(InitMsg{Verifier: bob, Beneficiary: fred}) require.NoError(t, err) - _, _, contractAddr, _, err := initHelperImpl(t, keeper, ctx, codeID, bob, bobPriv, string(initMsgBz), true, false, defaultGasForTests, -1, sdk.NewCoins()) + _, _, contractAddr, _, err := initHelperImpl(t, keeper, ctx, codeID, bob, nil, bobPriv, string(initMsgBz), true, false, defaultGasForTests, -1, sdk.NewCoins()) require.Empty(t, err) wasmCalls := int64(-1) @@ -673,7 +673,7 @@ func TestExecuteWithPanic(t *testing.T) { initMsgBz, err := json.Marshal(initMsg) require.NoError(t, err) - _, _, addr, _, err := initHelper(t, keeper, ctx, contractID, creator, creatorPrivKey, string(initMsgBz), false, false, defaultGasForTests) + _, _, addr, _, err := initHelper(t, keeper, ctx, contractID, creator, nil, creatorPrivKey, string(initMsgBz), false, false, defaultGasForTests) execMsgBz, err := wasmCtx.Encrypt([]byte(`{"panic":{}}`)) require.NoError(t, err) @@ -839,7 +839,7 @@ func TestExecuteWithStorageLoop(t *testing.T) { } initMsgBz, err := json.Marshal(initMsg) - _, _, addr, _, err := initHelper(t, keeper, ctx, contractID, creator, creatorPrivKey, string(initMsgBz), false, false, defaultGasForTests) + _, _, addr, _, err := initHelper(t, keeper, ctx, contractID, creator, nil, creatorPrivKey, string(initMsgBz), false, false, defaultGasForTests) // make sure we set a limit before calling var gasLimit uint64 = 400_002 diff --git a/x/compute/internal/keeper/mint_test.go b/x/compute/internal/keeper/mint_test.go index 46a4ccdff..faf09d788 100644 --- a/x/compute/internal/keeper/mint_test.go +++ b/x/compute/internal/keeper/mint_test.go @@ -75,7 +75,7 @@ func TestMintQuerier(t *testing.T) { initBz, err = testEncrypt(t, keeper, ctx, nil, govId, initBz) require.NoError(t, err) - ctx = PrepareInitSignedTx(t, keeper, ctx, creator, creatorPrivKey, initBz, govId, nil) + ctx = PrepareInitSignedTx(t, keeper, ctx, creator, nil, creatorPrivKey, initBz, govId, nil) govAddr, _, err := keeper.Instantiate(ctx, govId, creator, nil, initBz, "gidi gov", nil, nil) require.NoError(t, err) require.NotEmpty(t, govAddr) diff --git a/x/compute/internal/keeper/param_verification_test.go b/x/compute/internal/keeper/param_verification_test.go index 7d4796da3..a99919bf3 100644 --- a/x/compute/internal/keeper/param_verification_test.go +++ b/x/compute/internal/keeper/param_verification_test.go @@ -447,7 +447,7 @@ func TestMultiSigExecute(t *testing.T) { multisigAccount.address, walletB.String(), ) - _, _, contractAddress, _, error := initHelper(t, keeper, ctx, codeID, walletB, privKeyB, initMsg, true, false, defaultGasForTests) + _, _, contractAddress, _, error := initHelper(t, keeper, ctx, codeID, walletB, nil, privKeyB, initMsg, true, false, defaultGasForTests) require.Empty(t, error) execMsg := fmt.Sprintf(`{"transfer":{"amount":"10","recipient":"%s"}}`, walletB.String()) @@ -497,7 +497,7 @@ func TestMultiSigCallbacks(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/contract.wasm", sdk.Coins{}) // init - _, _, contractAddress, initEvents, error := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + _, _, contractAddress, initEvents, error := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) require.Empty(t, error) require.Equal(t, @@ -901,7 +901,7 @@ func TestWrongFundsNoFunds(t *testing.T) { require.NoError(t, err) nonce := initMsgBz[0:32] - ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privKeyA, initMsgBz, codeID, nil) + ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, nil, privKeyA, initMsgBz, codeID, nil) _, _, err = keeper.Instantiate(ctx, codeID, walletA, nil, initMsgBz, "demo contract 1", sdk.NewCoins(sdk.NewInt64Coin("denom", 1000)), nil) if err != nil { @@ -925,7 +925,7 @@ func TestWrongFundsSomeFunds(t *testing.T) { require.NoError(t, err) nonce := initMsgBz[0:32] - ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privKeyA, initMsgBz, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 200))) + ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, nil, privKeyA, initMsgBz, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 200))) _, _, err = keeper.Instantiate(ctx, codeID, walletA, nil, initMsgBz, "demo contract 1", sdk.NewCoins(sdk.NewInt64Coin("denom", 1000)), nil) if err != nil { @@ -959,7 +959,7 @@ func TestWrongMessage(t *testing.T) { notTheRealMsgBz, err := wasmCtx.Encrypt(notReallyTheMsg.Serialize()) require.NoError(t, err) - ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privKeyA, initMsgBz, codeID, nil) + ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, nil, privKeyA, initMsgBz, codeID, nil) _, _, err = keeper.Instantiate(ctx, codeID, walletA, nil, notTheRealMsgBz, "demo contract 1", sdk.NewCoins(sdk.NewInt64Coin("denom", 1000)), nil) if err != nil { @@ -974,9 +974,9 @@ func TestWrongContractAddress(t *testing.T) { initMsg := fmt.Sprintf(`{"decimals":10,"initial_balances":[{"address":"%s","amount":"108"},{"address":"%s","amount":"53"}],"name":"ReuvenPersonalRustCoin","symbol":"RPRC"}`, walletA.String(), walletB.String()) - _, _, contractAddress, _, stderr := initHelper(t, keeper, ctx, codeID, walletB, privKeyB, initMsg, true, false, defaultGasForTests) + _, _, contractAddress, _, stderr := initHelper(t, keeper, ctx, codeID, walletB, nil, privKeyB, initMsg, true, false, defaultGasForTests) require.Empty(t, stderr) - _, _, differentContractAddress, _, stderr := initHelper(t, keeper, ctx, codeID, walletB, privKeyB, initMsg, true, false, defaultGasForTests) + _, _, differentContractAddress, _, stderr := initHelper(t, keeper, ctx, codeID, walletB, nil, privKeyB, initMsg, true, false, defaultGasForTests) require.Empty(t, stderr) require.NotEqual(t, contractAddress, differentContractAddress) diff --git a/x/compute/internal/keeper/querier_test.go b/x/compute/internal/keeper/querier_test.go index eb17d16fd..64c01c401 100644 --- a/x/compute/internal/keeper/querier_test.go +++ b/x/compute/internal/keeper/querier_test.go @@ -63,7 +63,7 @@ func TestQueryContractLabel(t *testing.T) { label := "banana" - ctx = PrepareInitSignedTx(t, keeper, ctx, creator, privCreator, initMsgBz, contractID, deposit) + ctx = PrepareInitSignedTx(t, keeper, ctx, creator, nil, privCreator, initMsgBz, contractID, deposit) addr, _, err := keeper.Instantiate(ctx, contractID, creator, nil, initMsgBz, label, deposit, nil) require.NoError(t, err) diff --git a/x/compute/internal/keeper/recurse_test.go b/x/compute/internal/keeper/recurse_test.go index fbf27cf5d..fabc1cd49 100644 --- a/x/compute/internal/keeper/recurse_test.go +++ b/x/compute/internal/keeper/recurse_test.go @@ -81,7 +81,7 @@ func initRecurseContract(t *testing.T) (contract sdk.AccAddress, creator sdk.Acc initMsgBz, err := json.Marshal(initMsg) require.NoError(t, err) - _, _, contractAddr, _, initErr := initHelper(t, keeper, ctx, codeID, creator, creatorPriv, string(initMsgBz), true, false, defaultGasForTests) + _, _, contractAddr, _, initErr := initHelper(t, keeper, ctx, codeID, creator, nil, creatorPriv, string(initMsgBz), true, false, defaultGasForTests) require.Empty(t, initErr) return contractAddr, creator, ctx, keeper diff --git a/x/compute/internal/keeper/secret_contracts_exec_test.go b/x/compute/internal/keeper/secret_contracts_exec_test.go index a83c2bfae..67f689cc7 100644 --- a/x/compute/internal/keeper/secret_contracts_exec_test.go +++ b/x/compute/internal/keeper/secret_contracts_exec_test.go @@ -125,7 +125,7 @@ func TestState(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) // init - _, _, contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) require.Equal(t, 1, len(initEvents)) @@ -153,7 +153,7 @@ func TestState(t *testing.T) { func TestAddrValidateFunction(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, v1ContractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + _, _, v1ContractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) require.Empty(t, err) _, _, data, _, _, err := execHelper(t, keeper, ctx, v1ContractAddress, walletA, privKeyA, fmt.Sprintf(`{"validate_address":{"addr":"%s"}}`, v1ContractAddress), true, true, defaultGasForTests, 0) @@ -171,7 +171,7 @@ func TestAddrValidateFunction(t *testing.T) { func TestRandomEnv(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[randomContract], sdk.NewCoins()) - _, _, contractAddress, initEvents, initErr := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, `{"get_env":{}}`, true, true, defaultGasForTests, -1, sdk.NewCoins(sdk.NewInt64Coin("denom", 1))) + _, _, contractAddress, initEvents, initErr := initHelperImpl(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"get_env":{}}`, true, true, defaultGasForTests, -1, sdk.NewCoins(sdk.NewInt64Coin("denom", 1))) require.Empty(t, initErr) require.Len(t, initEvents, 1) @@ -256,7 +256,7 @@ func TestEnv(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddress, initEvents, initErr := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, `{"get_env":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, -1, sdk.NewCoins(sdk.NewInt64Coin("denom", 1))) + _, _, contractAddress, initEvents, initErr := initHelperImpl(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"get_env":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, -1, sdk.NewCoins(sdk.NewInt64Coin("denom", 1))) require.Empty(t, initErr) require.Len(t, initEvents, 1) @@ -353,7 +353,6 @@ func TestEnv(t *testing.T) { // require.Len(t, actualMessageInfo.Random, 44) // require.NotEqual(t, firstRandom, actualMessageInfo.Random) } else { - requireEvents(t, []ContractEvent{ { @@ -394,7 +393,7 @@ func TestNestedAttribute(t *testing.T) { // For more reference: https://github.com/scrtlabs/SecretNetwork/issues/1235 ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, v1ContractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + _, _, v1ContractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) require.Empty(t, err) _, _, data, events, _, err := execHelper(t, keeper, ctx, v1ContractAddress, walletA, privKeyA, `{"add_attribute_step1":{}}`, true, true, 10*defaultGasForTests, 0) @@ -434,7 +433,7 @@ func TestEmptyLogKeyValue(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) _, _, _, execEvents, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"empty_log_key_value":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) @@ -460,7 +459,7 @@ func TestExecNoLogs(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) // init - _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) _, _, _, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"no_logs":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) @@ -476,7 +475,7 @@ func TestEmptyData(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) _, _, data, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"empty_data":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) @@ -492,7 +491,7 @@ func TestNoData(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) _, _, data, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"no_data":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) @@ -508,7 +507,7 @@ func TestUnicodeData(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) _, _, data, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"unicode_data":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) @@ -524,7 +523,7 @@ func TestSecp256k1Verify(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) // https://paulmillr.com/noble/ @@ -650,7 +649,7 @@ func TestEd25519Verify(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) // https://paulmillr.com/noble/ @@ -719,7 +718,7 @@ func TestEd25519BatchVerify(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) // https://paulmillr.com/noble/ @@ -872,7 +871,7 @@ func TestSecp256k1RecoverPubkey(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) // https://paulmillr.com/noble/ @@ -910,7 +909,7 @@ func TestSecp256k1Sign(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) // priv iadRiuRKNZvAXwolxqzJvr60uiMDJTxOEzEwV8OK2ao= @@ -945,7 +944,7 @@ func TestEd25519Sign(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) // priv z01UNefH2yjRslwZMmcHssdHmdEjzVvbxjr+MloUEYo= @@ -983,7 +982,7 @@ func TestBenchmarkEd25519BatchVerifyAPI(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) start := time.Now() _, _, _, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1000,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg=="],"msgs":["YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU="]}}`, true, testContract.IsCosmWasmV1, math.MaxUint64, 0) @@ -1001,7 +1000,7 @@ func TestSleep(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) _, _, _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"sleep":{"ms":3000}}`, false, testContract.IsCosmWasmV1, defaultGasForTests, 0) @@ -1018,7 +1017,7 @@ func TestAllocateOnHeapFailBecauseMemoryLimit(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) _, _, data, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"allocate_on_heap":{"bytes":13631488}}`, false, testContract.IsCosmWasmV1, defaultGasForTests, 0) @@ -1038,7 +1037,7 @@ func TestAllocateOnHeapFailBecauseGasLimit(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) // ensure we get an out of gas panic @@ -1068,7 +1067,7 @@ func TestAllocateOnHeapMoreThanSGXHasFailBecauseMemoryLimit(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) _, _, data, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"allocate_on_heap":{"bytes":1073741824}}`, false, testContract.IsCosmWasmV1, 9_000_000, 0) @@ -1090,7 +1089,7 @@ func TestPassNullPointerToImports(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) tests := []string{ @@ -1121,7 +1120,7 @@ func TestPassNullPointerToImports(t *testing.T) { func TestV1ReplyLoop(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) _, _, data, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"sub_msg_loop":{"iter": 10}}`, true, true, math.MaxUint64, 0) @@ -1200,9 +1199,9 @@ func TestBankMsgSend(t *testing.T) { var contractAddress sdk.AccAddress if callType == "init" { - _, _, _, _, err = initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"bank_msg_send":{"to":"%s","amount":%s}}`, walletB.String(), test.input), false, contract.IsCosmWasmV1, defaultGasForTests, -1, sdk.NewCoins(sdk.NewInt64Coin("denom", 2), sdk.NewInt64Coin("assaf", 2))) + _, _, _, _, err = initHelperImpl(t, keeper, ctx, codeID, walletA, nil, privKeyA, fmt.Sprintf(`{"bank_msg_send":{"to":"%s","amount":%s}}`, walletB.String(), test.input), false, contract.IsCosmWasmV1, defaultGasForTests, -1, sdk.NewCoins(sdk.NewInt64Coin("denom", 2), sdk.NewInt64Coin("assaf", 2))) } else { - _, _, contractAddress, _, _ = initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, false, contract.IsCosmWasmV1, defaultGasForTests, -1, sdk.NewCoins(sdk.NewInt64Coin("denom", 2), sdk.NewInt64Coin("assaf", 2))) + _, _, contractAddress, _, _ = initHelperImpl(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, false, contract.IsCosmWasmV1, defaultGasForTests, -1, sdk.NewCoins(sdk.NewInt64Coin("denom", 2), sdk.NewInt64Coin("assaf", 2))) _, _, _, _, _, err = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"bank_msg_send":{"to":"%s","amount":%s}}`, walletB.String(), test.input), false, contract.IsCosmWasmV1, math.MaxUint64, 0) } @@ -1353,7 +1352,7 @@ func TestSendFunds(t *testing.T) { destinationCodeId, destinationHash = uploadCode(ctx, t, keeper, destinationVersion.WasmFilePath, helperWallet) if destinationType == "exec" { - _, _, destinationAddr, _, _ = initHelperImpl(t, keeper, ctx, destinationCodeId, helperWallet, helperPrivKey, `{"nop":{}}`, false, destinationVersion.IsCosmWasmV1, defaultGasForTests, -1, sdk.NewCoins()) + _, _, destinationAddr, _, _ = initHelperImpl(t, keeper, ctx, destinationCodeId, helperWallet, nil, helperPrivKey, `{"nop":{}}`, false, destinationVersion.IsCosmWasmV1, defaultGasForTests, -1, sdk.NewCoins()) } } @@ -1374,9 +1373,9 @@ func TestSendFunds(t *testing.T) { var wasmEvents []ContractEvent if originType == "init" { - _, _, originAddress, wasmEvents, err = initHelperImpl(t, keeper, ctx, originCodeId, fundingWallet, fundingWalletPrivKey, msg, false, originVersion.IsCosmWasmV1, defaultGasForTests, -1, stringToCoins(test.balancesBefore)) + _, _, originAddress, wasmEvents, err = initHelperImpl(t, keeper, ctx, originCodeId, fundingWallet, nil, fundingWalletPrivKey, msg, false, originVersion.IsCosmWasmV1, defaultGasForTests, -1, stringToCoins(test.balancesBefore)) } else if originType == "exec" { - _, _, originAddress, _, _ = initHelper(t, keeper, ctx, originCodeId, helperWallet, helperPrivKey, `{"nop":{}}`, false, originVersion.IsCosmWasmV1, defaultGasForTests) + _, _, originAddress, _, _ = initHelper(t, keeper, ctx, originCodeId, helperWallet, nil, helperPrivKey, `{"nop":{}}`, false, originVersion.IsCosmWasmV1, defaultGasForTests) _, _, _, wasmEvents, _, err = execHelperMultipleCoins(t, keeper, ctx, originAddress, fundingWallet, fundingWalletPrivKey, msg, false, originVersion.IsCosmWasmV1, math.MaxUint64, stringToCoins(test.balancesBefore), -1) } else { @@ -1389,7 +1388,7 @@ func TestSendFunds(t *testing.T) { if destinationType == "exec" { _, _, _, _, _, err = execHelperMultipleCoins(t, keeper, ctx, destinationAddr, fundingWallet, fundingWalletPrivKey, `{"no_data":{}}`, false, destinationVersion.IsCosmWasmV1, math.MaxUint64, stringToCoins(test.coinsToSend), wasmCount) } else { - _, _, destinationAddr, _, err = initHelperImpl(t, keeper, ctx, destinationCodeId, fundingWallet, fundingWalletPrivKey, `{"nop":{}}`, false, destinationVersion.IsCosmWasmV1, math.MaxUint64, wasmCount, stringToCoins(test.coinsToSend)) + _, _, destinationAddr, _, err = initHelperImpl(t, keeper, ctx, destinationCodeId, fundingWallet, nil, fundingWalletPrivKey, `{"nop":{}}`, false, destinationVersion.IsCosmWasmV1, math.MaxUint64, wasmCount, stringToCoins(test.coinsToSend)) } } @@ -1491,15 +1490,15 @@ func TestWasmMsgStructure(t *testing.T) { toAddress := sdk.AccAddress{} if secondCallType != "init" { - _, _, toAddress, _, err = initHelper(t, keeper, ctx, toCodeID, walletA, privKeyA, `{"nop":{}}`, true, to.IsCosmWasmV1, defaultGasForTests) + _, _, toAddress, _, err = initHelper(t, keeper, ctx, toCodeID, walletA, nil, privKeyA, `{"nop":{}}`, true, to.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) } fromAddress := sdk.AccAddress{} if firstCallType == "init" { - _, _, _, _, err = initHelper(t, keeper, ctx, fromCodeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_%s":{"code_id": %d, "addr": "%s", "code_hash": "%s", "label": "%s", "msg": "%s"}}`, secondCallType, toCodeID, toAddress, toCodeHash, "blabla", test.msg), test.isErrorEncrypted, true, defaultGasForTests) + _, _, _, _, err = initHelper(t, keeper, ctx, fromCodeID, walletA, nil, privKeyA, fmt.Sprintf(`{"call_to_%s":{"code_id": %d, "addr": "%s", "code_hash": "%s", "label": "%s", "msg": "%s"}}`, secondCallType, toCodeID, toAddress, toCodeHash, "blabla", test.msg), test.isErrorEncrypted, true, defaultGasForTests) } else if firstCallType == "exec" { - _, _, fromAddress, _, err = initHelper(t, keeper, ctx, fromCodeID, walletA, privKeyA, `{"nop":{}}`, true, from.IsCosmWasmV1, defaultGasForTests) + _, _, fromAddress, _, err = initHelper(t, keeper, ctx, fromCodeID, walletA, nil, privKeyA, `{"nop":{}}`, true, from.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) _, _, _, _, _, err = execHelper(t, keeper, ctx, fromAddress, walletA, privKeyA, fmt.Sprintf(`{"call_to_%s":{"code_id": %d, "addr": "%s", "code_hash": "%s", "label": "%s", "msg": "%s"}}`, secondCallType, toCodeID, toAddress, toCodeHash, "blabla", test.msg), test.isErrorEncrypted, true, math.MaxUint64, 0) } @@ -1533,9 +1532,9 @@ func TestCosmosMsgCustom(t *testing.T) { var contractAddress sdk.AccAddress if callType == "init" { - _, _, contractAddress, _, err = initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"cosmos_msg_custom":{}}`), false, contract.IsCosmWasmV1, defaultGasForTests, -1, sdk.NewCoins()) + _, _, contractAddress, _, err = initHelperImpl(t, keeper, ctx, codeID, walletA, nil, privKeyA, fmt.Sprintf(`{"cosmos_msg_custom":{}}`), false, contract.IsCosmWasmV1, defaultGasForTests, -1, sdk.NewCoins()) } else { - _, _, contractAddress, _, err = initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, false, contract.IsCosmWasmV1, defaultGasForTests, -1, sdk.NewCoins()) + _, _, contractAddress, _, err = initHelperImpl(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, false, contract.IsCosmWasmV1, defaultGasForTests, -1, sdk.NewCoins()) _, _, _, _, _, err = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"cosmos_msg_custom":{}}`), false, contract.IsCosmWasmV1, math.MaxUint64, 0) } @@ -1556,7 +1555,7 @@ func TestCosmosMsgCustom(t *testing.T) { func TestV1SendsFundsWithReply(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) _, _, _, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"deposit_to_contract":{}}`, false, true, defaultGasForTests, 200) require.Empty(t, err) @@ -1568,7 +1567,7 @@ func TestV1SendsFundsWithReply(t *testing.T) { func TestV1SendsFundsWithErrorWithReply(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) _, _, _, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"send_funds_with_error_with_reply":{}}`, false, true, math.MaxUint64, 0) @@ -1582,7 +1581,7 @@ func TestCallbackSanity(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) // init - _, _, contractAddress, initEvents, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, initEvents, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) requireEvents(t, @@ -1626,7 +1625,7 @@ func TestCodeHashExecCallExec(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) t.Run("GoodCodeHash", func(t *testing.T) { @@ -1709,7 +1708,7 @@ func TestGasIsChargedForExecCallbackToExec(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) // exec callback to exec @@ -1724,7 +1723,7 @@ func TestMsgSenderInCallback(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) _, _, _, events, _, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"callback_to_log_msg_sender":{"to":"%s","code_hash":"%s"}}`, addr.String(), codeHash), true, testContract.IsCosmWasmV1, defaultGasForTests, 0) @@ -1749,7 +1748,7 @@ func TestDepositToContract(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) contractCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr) @@ -1778,7 +1777,7 @@ func TestContractSendFunds(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) _, _, _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"deposit_to_contract":{}}`, false, testContract.IsCosmWasmV1, defaultGasForTests, 17) @@ -1809,10 +1808,10 @@ func TestContractSendFundsToExecCallback(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) - _, _, addr2, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr2, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) contractCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr) @@ -1843,10 +1842,10 @@ func TestContractSendFundsToExecCallbackNotEnough(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) - _, _, addr2, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr2, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) contractCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr) @@ -1881,7 +1880,7 @@ func TestExecCallbackContractError(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) // init - _, _, contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) require.Equal(t, 1, len(initEvents)) @@ -1901,7 +1900,7 @@ func TestExecCallbackBadParam(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) // init - _, _, contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) require.Equal(t, 1, len(initEvents)) @@ -1927,7 +1926,7 @@ func TestCallbackExecuteParamError(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) msg := fmt.Sprintf(`{"a":{"code_hash":"%s","contract_addr":"notanaddress","x":2,"y":3}}`, codeHash) @@ -1944,7 +1943,7 @@ func TestExecuteIllegalInputError(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) _, _, _, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `bad input`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) @@ -1964,7 +1963,7 @@ func TestExecContractError(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) t.Run("generic_err", func(t *testing.T) { @@ -2065,7 +2064,7 @@ func TestExecPanic(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) _, _, _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"panic":{}}`, false, testContract.IsCosmWasmV1, defaultGasForTests, 0) @@ -2081,7 +2080,7 @@ func TestCanonicalizeAddressErrors(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) require.Equal(t, 1, len(initEvents)) @@ -2099,7 +2098,7 @@ func TestV1ReplyChainAllSuccess(t *testing.T) { contractAddresses := make([]sdk.AccAddress, amountOfContracts) for i := uint64(0); i < amountOfContracts; i++ { - _, _, contractAddresses[i], _, _ = initHelper(t, keeper, ctx, codeIds[i], walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + _, _, contractAddresses[i], _, _ = initHelper(t, keeper, ctx, codeIds[i], walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) } executeDetails := make([]ExecuteDetails, amountOfContracts-1) @@ -2137,7 +2136,7 @@ func TestV1ReplyChainPartiallyReplied(t *testing.T) { contractAddresses := make([]sdk.AccAddress, amountOfContracts) for i := uint64(0); i < amountOfContracts; i++ { - _, _, contractAddresses[i], _, _ = initHelper(t, keeper, ctx, codeIds[i], walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + _, _, contractAddresses[i], _, _ = initHelper(t, keeper, ctx, codeIds[i], walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) } executeDetails := make([]ExecuteDetails, amountOfContracts-1) @@ -2181,7 +2180,7 @@ func TestV1ReplyChainWithError(t *testing.T) { contractAddresses := make([]sdk.AccAddress, amountOfContracts) for i := uint64(0); i < amountOfContracts; i++ { - _, _, contractAddresses[i], _, _ = initHelper(t, keeper, ctx, codeIds[i], walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + _, _, contractAddresses[i], _, _ = initHelper(t, keeper, ctx, codeIds[i], walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) } executeDetails := make([]ExecuteDetails, amountOfContracts-1) @@ -2215,7 +2214,7 @@ func TestV1ReplyChainWithError(t *testing.T) { func TestEvaporateGas(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[evaporateContract], sdk.NewCoins()) - _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"Nop":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"Nop":{}}`, true, true, defaultGasForTests) require.Empty(t, initErr) _, _, _, _, baseGasUsed, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"evaporate":{"amount":0}}`, true, true, defaultGasForTests, 0) @@ -2291,11 +2290,11 @@ func TestEvaporateGas(t *testing.T) { func TestCheckGas(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[evaporateContract], sdk.NewCoins()) - _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"Nop":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"Nop":{}}`, true, true, defaultGasForTests) require.Empty(t, initErr) - // 995 is the sum of all the overhead that goes into a contract call beyond the base cost (reading keys, calculations, etc) - baseContractUsage := types.InstanceCost + 1053 + // 1069 is the sum of all the overhead that goes into a contract call beyond the base cost (reading keys, calculations, etc) + baseContractUsage := types.InstanceCost + 1069 _, _, _, events, baseGasUsed, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"check_gas":{}}`, true, true, defaultGasForTests, 0) require.Empty(t, err) @@ -2310,7 +2309,7 @@ func TestCheckGas(t *testing.T) { func TestConsumeExact(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[evaporateContract], sdk.NewCoins()) - _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"Nop":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"Nop":{}}`, true, true, defaultGasForTests) require.Empty(t, initErr) // not sure where the 16 extra gas comes vs the previous check_gas test, but it makes everything play nice, so.... @@ -2364,7 +2363,7 @@ func TestConsumeExact(t *testing.T) { func TestLastMsgMarkerMultipleMsgsInATx(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop": {}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop": {}}`, true, true, defaultGasForTests) msgs := []string{`{"last_msg_marker_nop":{}}`, `{"last_msg_marker_nop":{}}`} @@ -2397,7 +2396,7 @@ func TestIBCHooksIncomingTransfer(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins(sdk.NewInt64Coin(test.localDenom, 1))) - _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) data := ibctransfertypes.FungibleTokenPacketData{ @@ -2569,7 +2568,7 @@ func TestIBCHooksOutgoingTransferAck(t *testing.T) { t.Run(test.name, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) require.Empty(t, initErr) testIcs20PacketSender := test.ics20PacketSender @@ -2729,7 +2728,7 @@ func TestIBCHooksOutgoingTransferTimeout(t *testing.T) { t.Run(test.name, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) require.Empty(t, initErr) testIcs20PacketSender := test.ics20PacketSender diff --git a/x/compute/internal/keeper/secret_contracts_init_test.go b/x/compute/internal/keeper/secret_contracts_init_test.go index 3932d7688..2e84810d5 100644 --- a/x/compute/internal/keeper/secret_contracts_init_test.go +++ b/x/compute/internal/keeper/secret_contracts_init_test.go @@ -21,7 +21,7 @@ func TestInitLogs(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) require.Equal(t, 1, len(initEvents)) requireEvents(t, @@ -43,13 +43,13 @@ func TestInitContractError(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) t.Run("generic_err", func(t *testing.T) { - _, _, _, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"contract_error":{"error_type":"generic_err"}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, _, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"contract_error":{"error_type":"generic_err"}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.NotNil(t, err.GenericErr) require.Contains(t, err.GenericErr.Msg, "la la 🤯") }) t.Run("invalid_base64", func(t *testing.T) { - _, _, _, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"contract_error":{"error_type":"invalid_base64"}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, _, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"contract_error":{"error_type":"invalid_base64"}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) if testContract.IsCosmWasmV1 { require.NotNil(t, err.GenericErr) @@ -60,7 +60,7 @@ func TestInitContractError(t *testing.T) { } }) t.Run("invalid_utf8", func(t *testing.T) { - _, _, _, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"contract_error":{"error_type":"invalid_utf8"}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, _, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"contract_error":{"error_type":"invalid_utf8"}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) if testContract.IsCosmWasmV1 { require.NotNil(t, err.GenericErr) @@ -71,7 +71,7 @@ func TestInitContractError(t *testing.T) { } }) t.Run("not_found", func(t *testing.T) { - _, _, _, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"contract_error":{"error_type":"not_found"}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, _, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"contract_error":{"error_type":"not_found"}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) if testContract.IsCosmWasmV1 { require.NotNil(t, err.GenericErr) @@ -82,7 +82,7 @@ func TestInitContractError(t *testing.T) { } }) t.Run("parse_err", func(t *testing.T) { - _, _, _, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"contract_error":{"error_type":"parse_err"}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, _, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"contract_error":{"error_type":"parse_err"}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) if testContract.IsCosmWasmV1 { require.NotNil(t, err.GenericErr) @@ -95,7 +95,7 @@ func TestInitContractError(t *testing.T) { } }) t.Run("serialize_err", func(t *testing.T) { - _, _, _, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"contract_error":{"error_type":"serialize_err"}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, _, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"contract_error":{"error_type":"serialize_err"}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) if testContract.IsCosmWasmV1 { require.NotNil(t, err.GenericErr) @@ -108,7 +108,7 @@ func TestInitContractError(t *testing.T) { } }) t.Run("unauthorized", func(t *testing.T) { - _, _, _, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"contract_error":{"error_type":"unauthorized"}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, _, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"contract_error":{"error_type":"unauthorized"}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) if testContract.IsCosmWasmV1 { // Not supported in V1 @@ -119,7 +119,7 @@ func TestInitContractError(t *testing.T) { } }) t.Run("underflow", func(t *testing.T) { - _, _, _, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"contract_error":{"error_type":"underflow"}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, _, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"contract_error":{"error_type":"underflow"}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) if testContract.IsCosmWasmV1 { // Not supported in V1 @@ -143,7 +143,7 @@ func TestInitParamError(t *testing.T) { codeHash := "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" msg := fmt.Sprintf(`{"callback":{"contract_addr":"notanaddress", "code_hash":"%s"}}`, codeHash) - _, _, _, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, msg, false, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, _, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, msg, false, testContract.IsCosmWasmV1, defaultGasForTests) require.Contains(t, initErr.Error(), "invalid address") }) @@ -164,7 +164,7 @@ func TestInitNotEncryptedInputError(t *testing.T) { initMsg := []byte(`{"nop":{}`) - ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privKey, initMsg, codeID, nil) + ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, nil, privKey, initMsg, codeID, nil) // init _, _, err := keeper.Instantiate(ctx, codeID, walletA, nil, initMsg, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) @@ -180,7 +180,7 @@ func TestQueryNotEncryptedInputError(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) _, err := keeper.QuerySmart(ctx, contractAddress, []byte(`{"owner":{}}`), false) @@ -197,7 +197,7 @@ func TestInitNoLogs(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) // init - _, _, _, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"no_logs":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, _, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"no_logs":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) ////require.Empty(t, initEvents) @@ -210,7 +210,7 @@ func TestInitPanic(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, _, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"panic":{}}`, false, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, _, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"panic":{}}`, false, testContract.IsCosmWasmV1, defaultGasForTests) require.NotNil(t, initErr.GenericErr) require.Contains(t, initErr.GenericErr.Msg, "the contract panicked") @@ -221,7 +221,7 @@ func TestInitPanic(t *testing.T) { func TestRemoveKeyInCache(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, _, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"test_remove_db":{}}`, true, true, defaultGasForTests) + _, _, _, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"test_remove_db":{}}`, true, true, defaultGasForTests) require.Nil(t, initErr.GenericErr) } @@ -231,7 +231,7 @@ func TestGasIsChargedForInitCallbackToInit(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, _, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"callback_to_init":{"code_id":%d,"code_hash":"%s"}}`, codeID, codeHash), true, testContract.IsCosmWasmV1, defaultGasForTests, 2, sdk.NewCoins()) + _, _, _, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, nil, privKeyA, fmt.Sprintf(`{"callback_to_init":{"code_id":%d,"code_hash":"%s"}}`, codeID, codeHash), true, testContract.IsCosmWasmV1, defaultGasForTests, 2, sdk.NewCoins()) require.Empty(t, err) }) } @@ -242,10 +242,10 @@ func TestGasIsChargedForInitCallbackToExec(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) - _, _, _, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"callback":{"contract_addr":"%s","code_hash":"%s"}}`, addr, codeHash), true, testContract.IsCosmWasmV1, defaultGasForTests, 2, sdk.NewCoins()) + _, _, _, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, nil, privKeyA, fmt.Sprintf(`{"callback":{"contract_addr":"%s","code_hash":"%s"}}`, addr, codeHash), true, testContract.IsCosmWasmV1, defaultGasForTests, 2, sdk.NewCoins()) require.Empty(t, err) }) } @@ -257,11 +257,11 @@ func TestInitCallbackBadParam(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) // init first - _, _, contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) require.Equal(t, 1, len(initEvents)) - _, _, secondContractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"callback_contract_bad_param":{"contract_addr":"%s"}}`, contractAddress), true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, secondContractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, fmt.Sprintf(`{"callback_contract_bad_param":{"contract_addr":"%s"}}`, contractAddress), true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, secondContractAddress) // require.Empty(t, initEvents) @@ -283,11 +283,11 @@ func TestInitCallbackContractError(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) require.Equal(t, 1, len(initEvents)) - _, _, secondContractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"callback_contract_error":{"contract_addr":"%s", "code_hash":"%s"}}`, contractAddress, codeHash), true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, secondContractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, fmt.Sprintf(`{"callback_contract_error":{"contract_addr":"%s", "code_hash":"%s"}}`, contractAddress, codeHash), true, testContract.IsCosmWasmV1, defaultGasForTests) require.NotNil(t, initErr.GenericErr) require.Contains(t, initErr.GenericErr.Msg, "la la 🤯") @@ -302,7 +302,7 @@ func TestContractSendFundsToInitCallbackNotEnough(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) contractCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr) @@ -334,7 +334,7 @@ func TestContractSendFundsToInitCallback(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) contractCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr) @@ -376,7 +376,7 @@ func TestInitCallbackToInit(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"callback_to_init":{"code_id":%d, "code_hash":"%s"}}`, codeID, codeHash), true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, fmt.Sprintf(`{"callback_to_init":{"code_id":%d, "code_hash":"%s"}}`, codeID, codeHash), true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) require.Equal(t, 2, len(initEvents)) @@ -418,7 +418,7 @@ func TestExecCallbackToInit(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) // init first contract - _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) // init second contract and callback to the first contract @@ -464,7 +464,7 @@ func TestCallbackFromInitAndCallbackEvents(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) // init first contract so we'd have someone to callback - _, _, firstContractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, firstContractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) requireEvents(t, @@ -478,7 +478,7 @@ func TestCallbackFromInitAndCallbackEvents(t *testing.T) { ) // init second contract and callback to the first contract - _, _, contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"callback":{"contract_addr":"%s", "code_hash": "%s"}}`, firstContractAddress.String(), codeHash), true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, fmt.Sprintf(`{"callback":{"contract_addr":"%s", "code_hash": "%s"}}`, firstContractAddress.String(), codeHash), true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) requireEvents(t, @@ -503,7 +503,7 @@ func TestGasIsChargedForExecCallbackToInit(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) // exec callback to init @@ -516,7 +516,7 @@ func TestGasIsChargedForExecCallbackToInit(t *testing.T) { func TestWasmTooHighInitialMemoryRuntimeFail(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[tooHighMemoryContract], sdk.NewCoins()) - _, _, _, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, false, false, defaultGasForTests) + _, _, _, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, false, false, defaultGasForTests) require.NotNil(t, err.GenericErr) require.Contains(t, err.GenericErr.Msg, "failed to initialize wasm memory") } @@ -546,7 +546,7 @@ func TestWasmWithFloatingPoints(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v010WithFloats], sdk.NewCoins()) - _, _, _, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, false, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, _, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, false, testContract.IsCosmWasmV1, defaultGasForTests) require.NotNil(t, err.GenericErr) require.Contains(t, err.GenericErr.Msg, "found floating point operation in module code") }) @@ -561,7 +561,7 @@ func TestCodeHashInvalid(t *testing.T) { enc, _ := wasmCtx.Encrypt(initMsg) - ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privWalletA, enc, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) + ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, nil, privWalletA, enc, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) _, _, err := keeper.Instantiate(ctx, codeID, walletA, nil, enc, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) require.Error(t, err) require.Contains(t, err.Error(), "failed to validate transaction") @@ -577,7 +577,7 @@ func TestCodeHashEmpty(t *testing.T) { enc, _ := wasmCtx.Encrypt(initMsg) - ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privWalletA, enc, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) + ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, nil, privWalletA, enc, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) _, _, err := keeper.Instantiate(ctx, codeID, walletA, nil, enc, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) require.Error(t, err) require.Contains(t, err.Error(), "failed to validate transaction") @@ -593,7 +593,7 @@ func TestCodeHashNotHex(t *testing.T) { enc, _ := wasmCtx.Encrypt(initMsg) - ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privWalletA, enc, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) + ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, nil, privWalletA, enc, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) _, _, err := keeper.Instantiate(ctx, codeID, walletA, nil, enc, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) require.Error(t, err) require.Contains(t, err.Error(), "failed to validate transaction") @@ -610,7 +610,7 @@ func TestCodeHashTooSmall(t *testing.T) { enc, _ := wasmCtx.Encrypt(initMsg) - ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privWalletA, enc, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) + ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, nil, privWalletA, enc, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) _, _, err := keeper.Instantiate(ctx, codeID, walletA, nil, enc, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) require.Error(t, err) require.Contains(t, err.Error(), "failed to validate transaction") @@ -627,7 +627,7 @@ func TestCodeHashTooBig(t *testing.T) { enc, _ := wasmCtx.Encrypt(initMsg) - ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privWalletA, enc, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) + ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, nil, privWalletA, enc, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) _, _, err := keeper.Instantiate(ctx, codeID, walletA, nil, enc, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) require.Error(t, err) @@ -647,7 +647,7 @@ func TestCodeHashWrong(t *testing.T) { enc, _ := wasmCtx.Encrypt(initMsg) - ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privWalletA, enc, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) + ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, nil, privWalletA, enc, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) _, _, err := keeper.Instantiate(ctx, codeID, walletA, nil, enc, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) require.Error(t, err) require.Contains(t, err.Error(), "failed to validate transaction") @@ -661,7 +661,7 @@ func TestCodeHashInitCallInit(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) t.Run("GoodCodeHash", func(t *testing.T) { - _, _, addr, events, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"%s","msg":"%s","label":"1"}}`, codeID, codeHash, `{\"nop\":{}}`), true, testContract.IsCosmWasmV1, defaultGasForTests, 2, sdk.NewCoins()) + _, _, addr, events, err := initHelperImpl(t, keeper, ctx, codeID, walletA, nil, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"%s","msg":"%s","label":"1"}}`, codeID, codeHash, `{\"nop\":{}}`), true, testContract.IsCosmWasmV1, defaultGasForTests, 2, sdk.NewCoins()) require.Empty(t, err) @@ -689,7 +689,7 @@ func TestCodeHashInitCallInit(t *testing.T) { ) }) t.Run("EmptyCodeHash", func(t *testing.T) { - _, _, _, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"","msg":"%s","label":"2"}}`, codeID, `{\"nop\":{}}`), false, testContract.IsCosmWasmV1, defaultGasForTests, 2, sdk.NewCoins()) + _, _, _, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, nil, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"","msg":"%s","label":"2"}}`, codeID, `{\"nop\":{}}`), false, testContract.IsCosmWasmV1, defaultGasForTests, 2, sdk.NewCoins()) require.NotEmpty(t, err) require.Contains(t, @@ -698,7 +698,7 @@ func TestCodeHashInitCallInit(t *testing.T) { ) }) t.Run("TooBigCodeHash", func(t *testing.T) { - _, _, _, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"%sa","msg":"%s","label":"3"}}`, codeID, codeHash, `{\"nop\":{}}`), true, testContract.IsCosmWasmV1, defaultGasForTests, 2, sdk.NewCoins()) + _, _, _, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, nil, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"%sa","msg":"%s","label":"3"}}`, codeID, codeHash, `{\"nop\":{}}`), true, testContract.IsCosmWasmV1, defaultGasForTests, 2, sdk.NewCoins()) require.NotEmpty(t, err) require.Contains(t, @@ -707,7 +707,7 @@ func TestCodeHashInitCallInit(t *testing.T) { ) }) t.Run("TooSmallCodeHash", func(t *testing.T) { - _, _, _, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"%s","msg":"%s","label":"4"}}`, codeID, codeHash[0:63], `{\"nop\":{}}`), false, testContract.IsCosmWasmV1, defaultGasForTests, 2, sdk.NewCoins()) + _, _, _, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, nil, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"%s","msg":"%s","label":"4"}}`, codeID, codeHash[0:63], `{\"nop\":{}}`), false, testContract.IsCosmWasmV1, defaultGasForTests, 2, sdk.NewCoins()) require.NotEmpty(t, err) require.Contains(t, @@ -716,7 +716,7 @@ func TestCodeHashInitCallInit(t *testing.T) { ) }) t.Run("IncorrectCodeHash", func(t *testing.T) { - _, _, _, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","msg":"%s","label":"5"}}`, codeID, `{\"nop\":{}}`), false, testContract.IsCosmWasmV1, defaultGasForTests, 2, sdk.NewCoins()) + _, _, _, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, nil, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","msg":"%s","label":"5"}}`, codeID, `{\"nop\":{}}`), false, testContract.IsCosmWasmV1, defaultGasForTests, 2, sdk.NewCoins()) require.NotEmpty(t, err) require.Contains(t, @@ -733,11 +733,11 @@ func TestCodeHashInitCallExec(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 1, sdk.NewCoins()) + _, _, addr, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 1, sdk.NewCoins()) require.Empty(t, err) t.Run("GoodCodeHash", func(t *testing.T) { - _, _, addr2, events, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr.String(), codeHash, `{\"c\":{\"x\":1,\"y\":1}}`), true, testContract.IsCosmWasmV1, defaultGasForTests, 2, sdk.NewCoins()) + _, _, addr2, events, err := initHelperImpl(t, keeper, ctx, codeID, walletA, nil, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr.String(), codeHash, `{\"c\":{\"x\":1,\"y\":1}}`), true, testContract.IsCosmWasmV1, defaultGasForTests, 2, sdk.NewCoins()) require.Empty(t, err) requireEvents(t, @@ -755,7 +755,7 @@ func TestCodeHashInitCallExec(t *testing.T) { ) }) t.Run("EmptyCodeHash", func(t *testing.T) { - _, _, _, _, err = initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"","msg":"%s"}}`, addr.String(), `{\"c\":{\"x\":1,\"y\":1}}`), false, testContract.IsCosmWasmV1, defaultGasForTests, 2, sdk.NewCoins()) + _, _, _, _, err = initHelperImpl(t, keeper, ctx, codeID, walletA, nil, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"","msg":"%s"}}`, addr.String(), `{\"c\":{\"x\":1,\"y\":1}}`), false, testContract.IsCosmWasmV1, defaultGasForTests, 2, sdk.NewCoins()) require.NotEmpty(t, err) require.Contains(t, @@ -764,7 +764,7 @@ func TestCodeHashInitCallExec(t *testing.T) { ) }) t.Run("TooBigCodeHash", func(t *testing.T) { - _, _, _, _, err = initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%sa","msg":"%s"}}`, addr.String(), codeHash, `{\"c\":{\"x\":1,\"y\":1}}`), true, testContract.IsCosmWasmV1, defaultGasForTests, 2, sdk.NewCoins()) + _, _, _, _, err = initHelperImpl(t, keeper, ctx, codeID, walletA, nil, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%sa","msg":"%s"}}`, addr.String(), codeHash, `{\"c\":{\"x\":1,\"y\":1}}`), true, testContract.IsCosmWasmV1, defaultGasForTests, 2, sdk.NewCoins()) require.NotEmpty(t, err) require.Contains(t, @@ -773,7 +773,7 @@ func TestCodeHashInitCallExec(t *testing.T) { ) }) t.Run("TooSmallCodeHash", func(t *testing.T) { - _, _, _, _, err = initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr.String(), codeHash[0:63], `{\"c\":{\"x\":1,\"y\":1}}`), false, testContract.IsCosmWasmV1, defaultGasForTests, 2, sdk.NewCoins()) + _, _, _, _, err = initHelperImpl(t, keeper, ctx, codeID, walletA, nil, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr.String(), codeHash[0:63], `{\"c\":{\"x\":1,\"y\":1}}`), false, testContract.IsCosmWasmV1, defaultGasForTests, 2, sdk.NewCoins()) require.NotEmpty(t, err) require.Contains(t, @@ -782,7 +782,7 @@ func TestCodeHashInitCallExec(t *testing.T) { ) }) t.Run("IncorrectCodeHash", func(t *testing.T) { - _, _, _, _, err = initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","msg":"%s"}}`, addr.String(), `{\"c\":{\"x\":1,\"y\":1}}`), false, testContract.IsCosmWasmV1, defaultGasForTests, 2, sdk.NewCoins()) + _, _, _, _, err = initHelperImpl(t, keeper, ctx, codeID, walletA, nil, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","msg":"%s"}}`, addr.String(), `{\"c\":{\"x\":1,\"y\":1}}`), false, testContract.IsCosmWasmV1, defaultGasForTests, 2, sdk.NewCoins()) require.NotEmpty(t, err) require.Contains(t, @@ -799,11 +799,11 @@ func TestCodeHashInitCallQuery(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) t.Run("GoodCodeHash", func(t *testing.T) { - _, _, addr2, events, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr.String(), codeHash, `{\"receive_external_query\":{\"num\":1}}`), true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr2, events, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr.String(), codeHash, `{\"receive_external_query\":{\"num\":1}}`), true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) requireEvents(t, @@ -817,7 +817,7 @@ func TestCodeHashInitCallQuery(t *testing.T) { ) }) t.Run("EmptyCodeHash", func(t *testing.T) { - _, _, _, _, err = initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"","msg":"%s"}}`, addr.String(), `{\"receive_external_query\":{\"num\":1}}`), true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, _, _, err = initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"","msg":"%s"}}`, addr.String(), `{\"receive_external_query\":{\"num\":1}}`), true, testContract.IsCosmWasmV1, defaultGasForTests) require.NotEmpty(t, err) require.Contains(t, @@ -826,7 +826,7 @@ func TestCodeHashInitCallQuery(t *testing.T) { ) }) t.Run("TooBigCodeHash", func(t *testing.T) { - _, _, _, _, err = initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%sa","msg":"%s"}}`, addr.String(), codeHash, `{\"receive_external_query\":{\"num\":1}}`), true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, _, _, err = initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%sa","msg":"%s"}}`, addr.String(), codeHash, `{\"receive_external_query\":{\"num\":1}}`), true, testContract.IsCosmWasmV1, defaultGasForTests) require.NotEmpty(t, err) require.Contains(t, @@ -835,7 +835,7 @@ func TestCodeHashInitCallQuery(t *testing.T) { ) }) t.Run("TooSmallCodeHash", func(t *testing.T) { - _, _, _, _, err = initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr.String(), codeHash[0:63], `{\"receive_external_query\":{\"num\":1}}`), true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, _, _, err = initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr.String(), codeHash[0:63], `{\"receive_external_query\":{\"num\":1}}`), true, testContract.IsCosmWasmV1, defaultGasForTests) require.NotEmpty(t, err) require.Contains(t, @@ -844,7 +844,7 @@ func TestCodeHashInitCallQuery(t *testing.T) { ) }) t.Run("IncorrectCodeHash", func(t *testing.T) { - _, _, _, _, err = initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","msg":"%s"}}`, addr.String(), `{\"receive_external_query\":{\"num\":1}}`), true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, _, _, err = initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","msg":"%s"}}`, addr.String(), `{\"receive_external_query\":{\"num\":1}}`), true, testContract.IsCosmWasmV1, defaultGasForTests) require.NotEmpty(t, err) require.Contains(t, @@ -861,7 +861,7 @@ func TestCodeHashExecCallInit(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) t.Run("GoodCodeHash", func(t *testing.T) { @@ -944,7 +944,7 @@ func TestLabelCollisionWhenMultipleCallbacksToInitFromSameContract(t *testing.T) t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) _, _, _, _, _, err = execHelperCustomWasmCount(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"%s","msg":"%s","label":"1"}}`, codeID, codeHash, `{\"nop\":{}}`), true, testContract.IsCosmWasmV1, defaultGasForTests, 0, 2) @@ -963,7 +963,7 @@ func TestInitIllegalInputError(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, _, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `bad input`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, _, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `bad input`, true, testContract.IsCosmWasmV1, defaultGasForTests) if testContract.IsCosmWasmV1 { require.NotNil(t, initErr.GenericErr) @@ -983,7 +983,7 @@ func TestBenchmarkSecp256k1VerifyAPI(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) start := time.Now() // https://paulmillr.com/noble/ @@ -1002,7 +1002,7 @@ func TestBenchmarkSecp256k1VerifyCrate(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) start := time.Now() // https://paulmillr.com/noble/ @@ -1018,7 +1018,7 @@ func TestInitCreateNewContract(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddress, ev, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) + _, _, contractAddress, ev, _ := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) _, _, _, ev, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"init_new_contract":{}}`, true, testContract.IsCosmWasmV1, math.MaxUint64, 0) require.Empty(t, err) diff --git a/x/compute/internal/keeper/secret_contracts_migrate_test.go b/x/compute/internal/keeper/secret_contracts_migrate_test.go index 3beaac3a4..b4a0bd8a7 100644 --- a/x/compute/internal/keeper/secret_contracts_migrate_test.go +++ b/x/compute/internal/keeper/secret_contracts_migrate_test.go @@ -14,7 +14,7 @@ func TestMigrateContract(t *testing.T) { newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[migrateContractV2], walletA) - _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"Nop":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"Nop":{}}`, true, true, defaultGasForTests) _, _, data, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"test":{}}`, true, true, defaultGasForTests, 0) require.Empty(t, execErr) @@ -33,7 +33,7 @@ func TestMigrateWithStorage(t *testing.T) { newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[migrateContractV2], walletA) - _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"Nop":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"Nop":{}}`, true, true, defaultGasForTests) _, _, data, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"test":{}}`, true, true, defaultGasForTests, 0) require.Empty(t, execErr) @@ -52,7 +52,7 @@ func TestMigrateContractFromDifferentAccount(t *testing.T) { newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[migrateContractV2], walletA) - _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"Nop":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"Nop":{}}`, true, true, defaultGasForTests) _, _, data, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"test":{}}`, true, true, defaultGasForTests, 0) require.Empty(t, execErr) diff --git a/x/compute/internal/keeper/secret_contracts_query_test.go b/x/compute/internal/keeper/secret_contracts_query_test.go index c8345ea5f..8f364fdd5 100644 --- a/x/compute/internal/keeper/secret_contracts_query_test.go +++ b/x/compute/internal/keeper/secret_contracts_query_test.go @@ -21,7 +21,7 @@ func TestQueryInputParamError(t *testing.T) { // init initMsg := fmt.Sprintf(`{"decimals":10,"initial_balances":[{"address":"%s","amount":"108"},{"address":"%s","amount":"53"}],"name":"ReuvenPersonalRustCoin","symbol":"RPRC"}`, walletA.String(), walletB.String()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, initMsg, true, false, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, initMsg, true, false, defaultGasForTests) require.Empty(t, err) // require.Empty(t, initEvents) @@ -36,7 +36,7 @@ func TestQueryContractError(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) t.Run("generic_err", func(t *testing.T) { @@ -138,7 +138,7 @@ func TestQueryInputStructureError(t *testing.T) { // init initMsg := fmt.Sprintf(`{"decimals":10,"initial_balances":[{"address":"%s","amount":"108"},{"address":"%s","amount":"53"}],"name":"ReuvenPersonalRustCoin","symbol":"RPRC"}`, walletA.String(), walletB.String()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, initMsg, true, false, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, initMsg, true, false, defaultGasForTests) require.Empty(t, err) // require.Empty(t, initEvents) @@ -153,7 +153,7 @@ func TestQueryPanic(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) _, queryErr := queryHelper(t, keeper, ctx, addr, `{"panic":{}}`, false, testContract.IsCosmWasmV1, defaultGasForTests) @@ -168,7 +168,7 @@ func TestExternalQueryWorks(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) _, _, data, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_external_query":{"to":"%s","code_hash":"%s"}}`, addr.String(), codeHash), true, testContract.IsCosmWasmV1, defaultGasForTests, 0) @@ -184,7 +184,7 @@ func TestExternalQueryCalleePanic(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) _, _, _, _, _, err = execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_external_query_panic":{"to":"%s","code_hash":"%s"}}`, addr.String(), codeHash), true, testContract.IsCosmWasmV1, defaultGasForTests, 0) @@ -200,7 +200,7 @@ func TestExternalQueryCalleeStdError(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) _, _, _, _, _, err = execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_external_query_error":{"to":"%s","code_hash":"%s"}}`, addr.String(), codeHash), true, testContract.IsCosmWasmV1, defaultGasForTests, 0) @@ -216,7 +216,7 @@ func TestExternalQueryCalleeDoesntExist(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) _, _, _, _, _, err = execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"send_external_query_error":{"to":"secret13l72vhjngmg55ykajxdnlalktwglyqjqv9pkq4","code_hash":"bla bla"}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) @@ -232,7 +232,7 @@ func TestExternalQueryBadSenderABI(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) _, _, _, _, _, err = execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_external_query_bad_abi":{"to":"%s","code_hash":"%s"}}`, addr.String(), codeHash), true, testContract.IsCosmWasmV1, defaultGasForTests, 0) @@ -255,7 +255,7 @@ func TestExternalQueryBadReceiverABI(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) _, _, _, _, _, err = execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_external_query_bad_abi_receiver":{"to":"%s","code_hash":"%s"}}`, addr.String(), codeHash), true, testContract.IsCosmWasmV1, defaultGasForTests, 0) @@ -279,7 +279,7 @@ func TestInfiniteQueryLoopKilledGracefullyByOOM(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) data, err := queryHelper(t, keeper, ctx, addr, fmt.Sprintf(`{"send_external_query_infinite_loop":{"to":"%s","code_hash":"%s"}}`, addr.String(), codeHash), true, testContract.IsCosmWasmV1, defaultGasForTests) @@ -296,7 +296,7 @@ func TestQueryRecursionLimitEnforcedInQueries(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) data, err := queryHelper(t, keeper, ctx, addr, fmt.Sprintf(`{"send_external_query_recursion_limit":{"to":"%s","code_hash":"%s", "depth":1}}`, addr.String(), codeHash), true, testContract.IsCosmWasmV1, 10*defaultGasForTests) @@ -314,7 +314,7 @@ func TestQueryRecursionLimitEnforcedInHandles(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) _, _, data, _, _, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_external_query_recursion_limit":{"to":"%s","code_hash":"%s", "depth":1}}`, addr.String(), codeHash), true, testContract.IsCosmWasmV1, 10*defaultGasForTests, 0) @@ -333,11 +333,11 @@ func TestQueryRecursionLimitEnforcedInInits(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) // Initialize a contract that we will be querying - _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) // Initialize the contract that will be running the test - _, _, addr, events, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"send_external_query_recursion_limit":{"to":"%s","code_hash":"%s", "depth":1}}`, addr.String(), codeHash), true, testContract.IsCosmWasmV1, 10*defaultGasForTests) + _, _, addr, events, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, fmt.Sprintf(`{"send_external_query_recursion_limit":{"to":"%s","code_hash":"%s", "depth":1}}`, addr.String(), codeHash), true, testContract.IsCosmWasmV1, 10*defaultGasForTests) require.Empty(t, err) require.Nil(t, err.GenericErr) @@ -357,7 +357,7 @@ func TestWriteToStorageDuringQuery(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) _, queryErr := queryHelper(t, keeper, ctx, addr, `{"write_to_storage": {}}`, false, testContract.IsCosmWasmV1, defaultGasForTests) @@ -372,7 +372,7 @@ func TestRemoveFromStorageDuringQuery(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) _, queryErr := queryHelper(t, keeper, ctx, addr, `{"remove_from_storage": {}}`, false, testContract.IsCosmWasmV1, defaultGasForTests) @@ -389,7 +389,7 @@ func TestGasIsChargedForExecExternalQuery(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) _, _, _, _, _, err := execHelperCustomWasmCount(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_external_query_depth_counter":{"to":"%s","depth":2,"code_hash":"%s"}}`, addr.String(), codeHash), true, testContract.IsCosmWasmV1, defaultGasForTests, 0, 3) @@ -405,10 +405,10 @@ func TestGasIsChargedForInitExternalQuery(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) - _, _, _, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"send_external_query_depth_counter":{"to":"%s","depth":2,"code_hash":"%s"}}`, addr.String(), codeHash), true, testContract.IsCosmWasmV1, defaultGasForTests, 3, sdk.NewCoins()) + _, _, _, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, nil, privKeyA, fmt.Sprintf(`{"send_external_query_depth_counter":{"to":"%s","depth":2,"code_hash":"%s"}}`, addr.String(), codeHash), true, testContract.IsCosmWasmV1, defaultGasForTests, 3, sdk.NewCoins()) require.Empty(t, err) }) } @@ -421,7 +421,7 @@ func TestGasIsChargedForQueryExternalQuery(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) _, err := queryHelperImpl(t, keeper, ctx, addr, fmt.Sprintf(`{"send_external_query_depth_counter":{"to":"%s","depth":2,"code_hash":"%s"}}`, addr.String(), codeHash), true, testContract.IsCosmWasmV1, defaultGasForTests, 3) @@ -435,7 +435,7 @@ func TestQueryGasPrice(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) t.Run("Query to Self Gas Price", func(t *testing.T) { @@ -453,7 +453,7 @@ func TestCodeHashExecCallQuery(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) t.Run("GoodCodeHash", func(t *testing.T) { @@ -522,7 +522,7 @@ func TestCodeHashQueryCallQuery(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) t.Run("GoodCodeHash", func(t *testing.T) { @@ -581,7 +581,7 @@ func TestCodeHashQueryCallQuery(t *testing.T) { func TestV1EndpointsSanity(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) _, _, data, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"increment":{"addition": 13}}`, true, true, math.MaxUint64, 0) @@ -601,7 +601,7 @@ func TestV1EndpointsSanity(t *testing.T) { func TestLastMsgMarker(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) _, err := execHelperMultipleMsgs(t, keeper, ctx, contractAddress, walletA, privKeyA, []string{`{"last_msg_marker":{}}`}, true, true, math.MaxUint64, 0) require.Empty(t, err) @@ -619,7 +619,7 @@ func TestLastMsgMarker(t *testing.T) { func TestLastMsgMarkerWithMoreThanOneTx(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) _, _, _, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"last_msg_marker":{}}`, true, true, math.MaxUint64, 0) require.Empty(t, err) @@ -640,7 +640,7 @@ func TestLastMsgMarkerWithMoreThanOneTx(t *testing.T) { func TestV1QueryWorksWithEnv(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"counter":{"counter":10, "expires":0}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"counter":{"counter":10, "expires":0}}`, true, true, defaultGasForTests) ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 10) queryRes, qErr := queryHelper(t, keeper, ctx, contractAddress, `{"get":{}}`, true, true, math.MaxUint64) @@ -656,7 +656,7 @@ func TestV1QueryWorksWithEnv(t *testing.T) { func TestV1ReplySanity(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) _, _, data, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"increment":{"addition": 13}}`, true, true, math.MaxUint64, 0) @@ -711,9 +711,9 @@ func TestV1QueryV010Contract(t *testing.T) { require.NoError(t, err) v010CodeHash := hex.EncodeToString(codeInfo.CodeHash) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) require.Empty(t, err) - _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, privKeyA, `{"init_from_v1":{"counter":190}}`, true, false, defaultGasForTests) + _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, nil, privKeyA, `{"init_from_v1":{"counter":190}}`, true, false, defaultGasForTests) require.Empty(t, err) msg := fmt.Sprintf(`{"query_v10":{"address":"%s", "code_hash":"%s"}}`, v010ContractAddress, v010CodeHash) diff --git a/x/compute/internal/keeper/secret_contracts_submsgs_test.go b/x/compute/internal/keeper/secret_contracts_submsgs_test.go index d41e10b7b..76af17081 100644 --- a/x/compute/internal/keeper/secret_contracts_submsgs_test.go +++ b/x/compute/internal/keeper/secret_contracts_submsgs_test.go @@ -15,7 +15,7 @@ import ( func TestV1ReplyOnMultipleSubmessages(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) _, _, data, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"multiple_sub_messages":{}}`, true, true, math.MaxUint64, 0) @@ -26,7 +26,7 @@ func TestV1ReplyOnMultipleSubmessages(t *testing.T) { func TestV1MultipleSubmessagesNoReply(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) _, _, data, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"multiple_sub_messages_no_reply":{}}`, true, true, math.MaxUint64, 0) @@ -47,7 +47,7 @@ func TestSendEncryptedAttributesFromInitWithoutSubmessageWithoutReply(t *testing t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddress, events, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"add_attributes":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, events, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"add_attributes":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) requireEvents(t, @@ -69,7 +69,7 @@ func TestSendEncryptedAttributesFromInitWithSubmessageWithoutReply(t *testing.T) t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddress, events, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"add_attributes_with_submessage":{"id":0}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, events, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"add_attributes_with_submessage":{"id":0}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) requireEvents(t, @@ -94,7 +94,7 @@ func TestSendEncryptedAttributesFromInitWithSubmessageWithoutReply(t *testing.T) func TestV1SendsEncryptedAttributesFromInitWithSubmessageWithReply(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, contractAddress, events, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"add_attributes_with_submessage":{"id":2200}}`, true, true, defaultGasForTests) + _, _, contractAddress, events, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"add_attributes_with_submessage":{"id":2200}}`, true, true, defaultGasForTests) require.Empty(t, err) requireEvents(t, @@ -124,7 +124,7 @@ func TestSendEncryptedAttributesFromExecuteWithoutSubmessageWithoutReply(t *test t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_attributes":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) @@ -148,7 +148,7 @@ func TestSendEncryptedAttributesFromExecuteWithSubmessageWithoutReply(t *testing t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_attributes_with_submessage":{"id":0}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0) require.Empty(t, err) @@ -175,7 +175,7 @@ func TestSendEncryptedAttributesFromExecuteWithSubmessageWithoutReply(t *testing func TestV1SendsEncryptedAttributesFromExecuteWithSubmessageWithReply(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) require.Empty(t, err) _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_attributes_with_submessage":{"id":2200}}`, true, true, defaultGasForTests, 0) require.Empty(t, err) @@ -207,7 +207,7 @@ func TestSendPlaintextFromInitWithoutSubmessageWithoutReply(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddress, events, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"add_plaintext_attributes":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, true) + _, _, contractAddress, events, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"add_plaintext_attributes":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, true) require.Empty(t, err) requireEvents(t, @@ -229,7 +229,7 @@ func TestSendPlaintextAttributesFromInitWithSubmessageWithoutReply(t *testing.T) t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddress, events, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"add_plaintext_attributes_with_submessage":{"id":0}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, true) + _, _, contractAddress, events, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"add_plaintext_attributes_with_submessage":{"id":0}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, true) require.Empty(t, err) requireEvents(t, @@ -254,7 +254,7 @@ func TestSendPlaintextAttributesFromInitWithSubmessageWithoutReply(t *testing.T) func TestV1SendsPlaintextAttributesFromInitWithSubmessageWithReply(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, contractAddress, events, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"add_plaintext_attributes_with_submessage":{"id":2300}}`, true, true, defaultGasForTests, true) + _, _, contractAddress, events, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"add_plaintext_attributes_with_submessage":{"id":2300}}`, true, true, defaultGasForTests, true) require.Empty(t, err) requireEvents(t, @@ -284,7 +284,7 @@ func TestSendPlaintextAttributesFromExecuteWithoutSubmessageWithoutReply(t *test t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_plaintext_attributes":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0, true) require.Empty(t, err) @@ -308,7 +308,7 @@ func TestSendPlaintextAttributesFromExecuteWithSubmessageWithoutReply(t *testing t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, err) _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_plaintext_attributes_with_submessage":{"id":0}}`, true, testContract.IsCosmWasmV1, defaultGasForTests, 0, true) require.Empty(t, err) @@ -335,7 +335,7 @@ func TestSendPlaintextAttributesFromExecuteWithSubmessageWithoutReply(t *testing func TestV1SendsPlaintextAttributesFromExecuteWithSubmessageWithReply(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) require.Empty(t, err) _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_plaintext_attributes_with_submessage":{"id":2300}}`, true, true, defaultGasForTests, 0, true) require.Empty(t, err) @@ -365,7 +365,7 @@ func TestV1SendsPlaintextAttributesFromExecuteWithSubmessageWithReply(t *testing func TestV1SendsEncryptedEventsFromInitWithoutSubmessageWithoutReply(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - nonce, ctx, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"add_events":{}}`, true, true, defaultGasForTests) + nonce, ctx, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"add_events":{}}`, true, true, defaultGasForTests) require.Empty(t, err) @@ -416,7 +416,7 @@ func TestV1SendsEncryptedEventsFromInitWithoutSubmessageWithoutReply(t *testing. func TestV1SendsEncryptedEventsFromInitWithSubmessageWithoutReply(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - nonce, ctx, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"add_events_with_submessage":{"id":0}}`, true, true, defaultGasForTests) + nonce, ctx, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"add_events_with_submessage":{"id":0}}`, true, true, defaultGasForTests) require.Empty(t, err) events := ctx.EventManager().Events() @@ -505,7 +505,7 @@ func TestV1SendsEncryptedEventsFromInitWithSubmessageWithoutReply(t *testing.T) func TestV1SendsEncryptedEventsFromInitWithSubmessageWithReply(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - nonce, ctx, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"add_events_with_submessage":{"id":2400}}`, true, true, defaultGasForTests) + nonce, ctx, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"add_events_with_submessage":{"id":2400}}`, true, true, defaultGasForTests) require.Empty(t, err) events := ctx.EventManager().Events() @@ -632,7 +632,7 @@ func TestV1SendsEncryptedEventsFromInitWithSubmessageWithReply(t *testing.T) { func TestV1SendsEncryptedEventsFromExecuteWithoutSubmessageWithoutReply(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) require.Empty(t, err) nonce, ctx, _, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_events":{}}`, true, true, defaultGasForTests, 0) require.Empty(t, err) @@ -685,7 +685,7 @@ func TestV1SendsEncryptedEventsFromExecuteWithoutSubmessageWithoutReply(t *testi func TestV1SendsEncryptedEventsFromExecuteWithSubmessageWithoutReply(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) require.Empty(t, err) nonce, ctx, _, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_events_with_submessage":{"id":0}}`, true, true, defaultGasForTests, 0) require.Empty(t, err) @@ -776,7 +776,7 @@ func TestV1SendsEncryptedEventsFromExecuteWithSubmessageWithoutReply(t *testing. func TestV1SendsEncryptedEventsFromExecuteWithSubmessageWithReply(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) require.Empty(t, err) nonce, ctx, _, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_events_with_submessage":{"id":2400}}`, true, true, defaultGasForTests, 0) require.Empty(t, err) @@ -905,7 +905,7 @@ func TestV1SendsEncryptedEventsFromExecuteWithSubmessageWithReply(t *testing.T) func TestV1SendsMixedLogsFromInitWithoutSubmessageWithoutReply(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - nonce, ctx, contractAddress, logs, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"add_mixed_attributes_and_events":{}}`, true, true, defaultGasForTests, true) + nonce, ctx, contractAddress, logs, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"add_mixed_attributes_and_events":{}}`, true, true, defaultGasForTests, true) require.Empty(t, err) @@ -948,7 +948,7 @@ func TestV1SendsMixedLogsFromInitWithoutSubmessageWithoutReply(t *testing.T) { func TestV1SendsMixedAttributesAndEventsFromInitWithSubmessageWithoutReply(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - nonce, ctx, contractAddress, logs, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"add_mixed_attributes_and_events_with_submessage":{"id":0}}`, true, true, defaultGasForTests) + nonce, ctx, contractAddress, logs, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"add_mixed_attributes_and_events_with_submessage":{"id":0}}`, true, true, defaultGasForTests) require.Empty(t, err) events := ctx.EventManager().Events() @@ -1015,7 +1015,7 @@ func TestV1SendsMixedAttributesAndEventsFromInitWithSubmessageWithoutReply(t *te func TestV1SendsMixedAttributesAndEventsFromInitWithSubmessageWithReply(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - nonce, ctx, contractAddress, logs, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"add_mixed_attributes_and_events_with_submessage":{"id":2500}}`, true, true, defaultGasForTests) + nonce, ctx, contractAddress, logs, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"add_mixed_attributes_and_events_with_submessage":{"id":2500}}`, true, true, defaultGasForTests) require.Empty(t, err) events := ctx.EventManager().Events() @@ -1106,7 +1106,7 @@ func TestV1SendsMixedAttributesAndEventsFromInitWithSubmessageWithReply(t *testi func TestV1SendsMixedAttributesAndEventsFromExecuteWithoutSubmessageWithoutReply(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) require.Empty(t, err) nonce, ctx, _, logs, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_mixed_attributes_and_events":{}}`, true, true, defaultGasForTests, 0, true) require.Empty(t, err) @@ -1151,7 +1151,7 @@ func TestV1SendsMixedAttributesAndEventsFromExecuteWithoutSubmessageWithoutReply func TestV1SendsMixedAttributesAndEventsFromExecuteWithSubmessageWithoutReply(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) require.Empty(t, err) nonce, ctx, _, logs, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_mixed_attributes_and_events_with_submessage":{"id":0}}`, true, true, defaultGasForTests, 0) require.Empty(t, err) @@ -1220,7 +1220,7 @@ func TestV1SendsMixedAttributesAndEventsFromExecuteWithSubmessageWithoutReply(t func TestV1SendsMixedAttributesAndEventsFromExecuteWithSubmessageWithReply(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) require.Empty(t, err) nonce, ctx, _, logs, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_mixed_attributes_and_events_with_submessage":{"id":2500}}`, true, true, defaultGasForTests, 0) require.Empty(t, err) @@ -1319,7 +1319,7 @@ func TestSubmessageGasExceedingMessageGas(t *testing.T) { _, ok := r.(sdk.ErrorOutOfGas) require.True(t, ok, "%+v", r) }() - _, _, _, _, _ = initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"measure_gas_for_submessage":{"id":0}}`, false, true, defaultGasForTests) + _, _, _, _, _ = initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"measure_gas_for_submessage":{"id":0}}`, false, true, defaultGasForTests) } func TestReplyGasExceedingMessageGas(t *testing.T) { @@ -1331,5 +1331,5 @@ func TestReplyGasExceedingMessageGas(t *testing.T) { _, ok := r.(sdk.ErrorOutOfGas) require.True(t, ok, "%+v", r) }() - _, _, _, _, _ = initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"measure_gas_for_submessage":{"id":2600}}`, false, true, defaultGasForTests) + _, _, _, _, _ = initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"measure_gas_for_submessage":{"id":2600}}`, false, true, defaultGasForTests) } diff --git a/x/compute/internal/keeper/secret_contracts_utils_test.go b/x/compute/internal/keeper/secret_contracts_utils_test.go index 82f1debcf..4565b54d2 100644 --- a/x/compute/internal/keeper/secret_contracts_utils_test.go +++ b/x/compute/internal/keeper/secret_contracts_utils_test.go @@ -592,15 +592,15 @@ func execTxBuilderImpl( func initHelper( t *testing.T, keeper Keeper, ctx sdk.Context, - codeID uint64, creator sdk.AccAddress, creatorPrivKey crypto.PrivKey, initMsg string, + codeID uint64, creator, admin sdk.AccAddress, creatorPrivKey crypto.PrivKey, initMsg string, isErrorEncrypted bool, isV1Contract bool, gas uint64, shouldSkipAttributes ...bool, ) ([]byte, sdk.Context, sdk.AccAddress, []ContractEvent, cosmwasm.StdError) { - return initHelperImpl(t, keeper, ctx, codeID, creator, creatorPrivKey, initMsg, isErrorEncrypted, isV1Contract, gas, -1, sdk.NewCoins(), shouldSkipAttributes...) + return initHelperImpl(t, keeper, ctx, codeID, creator, admin, creatorPrivKey, initMsg, isErrorEncrypted, isV1Contract, gas, -1, sdk.NewCoins(), shouldSkipAttributes...) } func initHelperImpl( t *testing.T, keeper Keeper, ctx sdk.Context, - codeID uint64, creator sdk.AccAddress, creatorPrivKey crypto.PrivKey, initMsg string, + codeID uint64, creator, admin sdk.AccAddress, creatorPrivKey crypto.PrivKey, initMsg string, isErrorEncrypted bool, isV1Contract bool, gas uint64, wasmCallCount int64, sentFunds sdk.Coins, shouldSkipAttributes ...bool, ) ([]byte, sdk.Context, sdk.AccAddress, []ContractEvent, cosmwasm.StdError) { codeInfo, err := keeper.GetCodeInfo(ctx, codeID) @@ -628,9 +628,9 @@ func initHelperImpl( log.NewNopLogger(), ).WithGasMeter(gasMeter) - ctx = PrepareInitSignedTx(t, keeper, ctx, creator, creatorPrivKey, initMsgBz, codeID, sentFunds) + ctx = PrepareInitSignedTx(t, keeper, ctx, creator, admin, creatorPrivKey, initMsgBz, codeID, sentFunds) // make the label a random base64 string, because why not? - contractAddress, _, err := keeper.Instantiate(ctx, codeID, creator, creator, initMsgBz, base64.RawURLEncoding.EncodeToString(nonce), sentFunds, nil) + contractAddress, _, err := keeper.Instantiate(ctx, codeID, creator, admin, initMsgBz, base64.RawURLEncoding.EncodeToString(nonce), sentFunds, nil) if wasmCallCount < 0 { // default, just check that at least 1 call happened diff --git a/x/compute/internal/keeper/secret_contracts_v010_test.go b/x/compute/internal/keeper/secret_contracts_v010_test.go index 6f5cacac7..e4291fa07 100644 --- a/x/compute/internal/keeper/secret_contracts_v010_test.go +++ b/x/compute/internal/keeper/secret_contracts_v010_test.go @@ -18,7 +18,7 @@ func TestSanity(t *testing.T) { // init initMsg := fmt.Sprintf(`{"decimals":10,"initial_balances":[{"address":"%s","amount":"108"},{"address":"%s","amount":"53"}],"name":"ReuvenPersonalRustCoin","symbol":"RPRC"}`, walletA.String(), walletB.String()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, initMsg, true, false, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, initMsg, true, false, defaultGasForTests) require.Empty(t, err) // require.Empty(t, initEvents) @@ -62,7 +62,7 @@ func TestSanity(t *testing.T) { func TestEncryptedAndPlaintextLogs(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[plaintextLogsContract], sdk.NewCoins()) - _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{}`, true, false, defaultGasForTests) + _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{}`, true, false, defaultGasForTests) require.Empty(t, err) _, _, _, events, _, err := execHelperCustomWasmCount(t, keeper, ctx, addr, walletA, privKeyA, "{}", true, false, defaultGasForTests, 0, 1) @@ -85,7 +85,7 @@ func TestEncryptedAndPlaintextLogs(t *testing.T) { func TestContractTryToSendFundsFromSomeoneElse(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v010Contract], sdk.NewCoins()) - _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) require.Empty(t, initErr) _, _, _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"deposit_to_contract":{}}`, false, false, defaultGasForTests, 17) @@ -113,9 +113,9 @@ func TestV010BankMsgSendFrom(t *testing.T) { var contractAddress sdk.AccAddress if callType == "init" { - _, _, _, _, err = initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"bank_msg_send":{"to":"%s","from":"%s","amount":[{"amount":"1","denom":"denom"}]}}`, walletB.String(), walletA.String()), false, false, defaultGasForTests, -1, sdk.NewCoins()) + _, _, _, _, err = initHelperImpl(t, keeper, ctx, codeID, walletA, nil, privKeyA, fmt.Sprintf(`{"bank_msg_send":{"to":"%s","from":"%s","amount":[{"amount":"1","denom":"denom"}]}}`, walletB.String(), walletA.String()), false, false, defaultGasForTests, -1, sdk.NewCoins()) } else { - _, _, contractAddress, _, _ = initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, false, false, defaultGasForTests, -1, sdk.NewCoins()) + _, _, contractAddress, _, _ = initHelperImpl(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, false, false, defaultGasForTests, -1, sdk.NewCoins()) _, _, _, _, _, err = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"bank_msg_send":{"to":"%s","from":"%s","amount":[{"amount":"1","denom":"denom"}]}}`, walletB.String(), walletA.String()), false, false, math.MaxUint64, 0) } @@ -150,9 +150,9 @@ func TestBankMsgBurn(t *testing.T) { var contractAddress sdk.AccAddress if callType == "init" { - _, _, _, _, err = initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"bank_msg_burn":{"amount":[{"amount":"1","denom":"denom"}]}}`), false, false, defaultGasForTests, -1, test.sentFunds) + _, _, _, _, err = initHelperImpl(t, keeper, ctx, codeID, walletA, nil, privKeyA, fmt.Sprintf(`{"bank_msg_burn":{"amount":[{"amount":"1","denom":"denom"}]}}`), false, false, defaultGasForTests, -1, test.sentFunds) } else { - _, _, contractAddress, _, _ = initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, false, false, defaultGasForTests, -1, test.sentFunds) + _, _, contractAddress, _, _ = initHelperImpl(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, false, false, defaultGasForTests, -1, test.sentFunds) _, _, _, _, _, err = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"bank_msg_burn":{"amount":[{"amount":"1","denom":"denom"}]}}`), false, false, math.MaxUint64, 0) } diff --git a/x/compute/internal/keeper/secret_contracts_v1_v010_test.go b/x/compute/internal/keeper/secret_contracts_v1_v010_test.go index ffad28e45..7fe8d5e83 100644 --- a/x/compute/internal/keeper/secret_contracts_v1_v010_test.go +++ b/x/compute/internal/keeper/secret_contracts_v1_v010_test.go @@ -28,7 +28,7 @@ func TestV1InitV010ContractWithReply(t *testing.T) { require.NoError(t, err) v010CodeHash := hex.EncodeToString(codeInfo.CodeHash) - _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) msg := fmt.Sprintf(`{"init_v10":{"counter":80, "code_id":%d, "code_hash":"%s"}}`, v010CodeID, v010CodeHash) _, _, data, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, msg, true, true, math.MaxUint64, 0) @@ -59,9 +59,9 @@ func TestV1ExecuteV010ContractWithReply(t *testing.T) { require.NoError(t, err) v010CodeHash := hex.EncodeToString(codeInfo.CodeHash) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) require.Empty(t, err) - _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, nil, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) require.Empty(t, err) msg := fmt.Sprintf(`{"exec_v10":{"address":"%s", "code_hash":"%s"}}`, v010ContractAddress, v010CodeHash) @@ -85,7 +85,7 @@ func TestV1InitV010ContractNoReply(t *testing.T) { require.NoError(t, err) v010CodeHash := hex.EncodeToString(codeInfo.CodeHash) - _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) msg := fmt.Sprintf(`{"init_v10_no_reply":{"counter":180, "code_id":%d, "code_hash":"%s"}}`, v010CodeID, v010CodeHash) _, _, _, ev, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, msg, true, true, math.MaxUint64, 0) @@ -126,9 +126,9 @@ func TestV1ExecuteV010ContractNoReply(t *testing.T) { require.NoError(t, err) v010CodeHash := hex.EncodeToString(codeInfo.CodeHash) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) require.Empty(t, err) - _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, nil, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) require.Empty(t, err) msg := fmt.Sprintf(`{"exec_v10_no_reply":{"address":"%s", "code_hash":"%s"}}`, v010ContractAddress, v010CodeHash) @@ -157,7 +157,7 @@ func TestV1InitV010ContractWithReplyWithError(t *testing.T) { require.NoError(t, err) v010CodeHash := hex.EncodeToString(codeInfo.CodeHash) - _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) msg := fmt.Sprintf(`{"init_v10_with_error":{"code_id":%d, "code_hash":"%s"}}`, v010CodeID, v010CodeHash) _, _, _, _, _, err = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, msg, true, true, math.MaxUint64, 0) @@ -178,9 +178,9 @@ func TestV1ExecuteV010ContractWithReplyWithError(t *testing.T) { require.NoError(t, err) v010CodeHash := hex.EncodeToString(codeInfo.CodeHash) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) require.Empty(t, err) - _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, nil, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) require.Empty(t, err) msg := fmt.Sprintf(`{"exec_v10_with_error":{"address":"%s", "code_hash":"%s"}}`, v010ContractAddress, v010CodeHash) @@ -203,7 +203,7 @@ func TestV1InitV010ContractNoReplyWithError(t *testing.T) { require.NoError(t, err) v010CodeHash := hex.EncodeToString(codeInfo.CodeHash) - _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) msg := fmt.Sprintf(`{"init_v10_no_reply_with_error":{"code_id":%d, "code_hash":"%s"}}`, v010CodeID, v010CodeHash) _, _, data, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, msg, true, true, math.MaxUint64, 0) @@ -225,9 +225,9 @@ func TestV1ExecuteV010ContractNoReplyWithError(t *testing.T) { require.NoError(t, err) v010CodeHash := hex.EncodeToString(codeInfo.CodeHash) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) require.Empty(t, err) - _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, nil, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) require.Empty(t, err) msg := fmt.Sprintf(`{"exec_v10_no_reply_with_error":{"address":"%s", "code_hash":"%s"}}`, v010ContractAddress, v010CodeHash) @@ -251,9 +251,9 @@ func TestV1QueryV010ContractWithError(t *testing.T) { require.NoError(t, err) v010CodeHash := hex.EncodeToString(codeInfo.CodeHash) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) require.Empty(t, err) - _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, nil, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) require.Empty(t, err) msg := fmt.Sprintf(`{"query_v10_with_error":{"address":"%s", "code_hash":"%s"}}`, v010ContractAddress, v010CodeHash) @@ -273,7 +273,7 @@ func TestV010InitV1ContractFromInitWithOkResponse(t *testing.T) { v010CodeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") require.NoError(t, err) - _, _, contractAddress, initEvents, err := initHelper(t, keeper, ctx, v010CodeID, walletA, privKeyA, fmt.Sprintf(`{"callback_to_init":{"code_id":%d, "code_hash":"%s"}}`, codeID, codeHash), true, true, defaultGasForTests) + _, _, contractAddress, initEvents, err := initHelper(t, keeper, ctx, v010CodeID, walletA, nil, privKeyA, fmt.Sprintf(`{"callback_to_init":{"code_id":%d, "code_hash":"%s"}}`, codeID, codeHash), true, true, defaultGasForTests) queryRes, qErr := queryHelper(t, keeper, ctx, contractAddress, `{"get_contract_version":{}}`, true, false, math.MaxUint64) require.Empty(t, qErr) @@ -306,7 +306,7 @@ func TestV010InitV1ContractFromExecuteWithOkResponse(t *testing.T) { v010CodeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") require.NoError(t, err) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, nil, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) require.Empty(t, err) queryRes, qErr := queryHelper(t, keeper, ctx, contractAddress, `{"get_contract_version":{}}`, true, false, math.MaxUint64) @@ -344,9 +344,9 @@ func TestV010ExecuteV1ContractFromInitWithOkResponse(t *testing.T) { v010CodeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") require.NoError(t, err) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"counter":{"counter":199, "expires":100}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"counter":{"counter":199, "expires":100}}`, true, true, defaultGasForTests) require.Empty(t, err) - _, _, _, _, err = initHelper(t, keeper, ctx, v010CodeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, contractAddress.String(), codeHash, `{\"increment\":{\"addition\": 1}}`), true, true, defaultGasForTests) + _, _, _, _, err = initHelper(t, keeper, ctx, v010CodeID, walletA, nil, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, contractAddress.String(), codeHash, `{\"increment\":{\"addition\": 1}}`), true, true, defaultGasForTests) require.Empty(t, err) queryRes, qErr := queryHelper(t, keeper, ctx, contractAddress, `{"get":{}}`, true, true, math.MaxUint64) @@ -368,8 +368,8 @@ func TestV010ExecuteV1ContractFromExecuteWithOkResponse(t *testing.T) { v010CodeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") require.NoError(t, err) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"counter":{"counter":299, "expires":100}}`, true, true, defaultGasForTests) - _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"counter":{"counter":299, "expires":100}}`, true, true, defaultGasForTests) + _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, nil, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) _, _, _, _, _, err = execHelper(t, keeper, ctx, v010ContractAddress, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, contractAddress.String(), codeHash, `{\"increment\":{\"addition\": 1}}`), true, true, defaultGasForTests, 0) require.Empty(t, err) @@ -393,8 +393,8 @@ func TestV010QueryV1ContractFromInitWithOkResponse(t *testing.T) { v010CodeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") require.NoError(t, err) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) - _, _, v010ContractAddress, events, err := initHelper(t, keeper, ctx, v010CodeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, contractAddress.String(), codeHash, `{\"receive_external_query_v1\":{\"num\":1}}`), true, true, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + _, _, v010ContractAddress, events, err := initHelper(t, keeper, ctx, v010CodeID, walletA, nil, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, contractAddress.String(), codeHash, `{\"receive_external_query_v1\":{\"num\":1}}`), true, true, defaultGasForTests) require.Empty(t, err) requireEvents(t, []ContractEvent{ @@ -416,8 +416,8 @@ func TestV010QueryV1ContractFromExecuteWithOkResponse(t *testing.T) { v010CodeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") require.NoError(t, err) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) - _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, nil, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) _, _, _, events, _, err := execHelper(t, keeper, ctx, v010ContractAddress, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, contractAddress.String(), codeHash, `{\"receive_external_query_v1\":{\"num\":1}}`), true, true, defaultGasForTests, 0) require.Empty(t, err) @@ -441,7 +441,7 @@ func TestV010InitV1ContractFromInitWithErrResponse(t *testing.T) { v010CodeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") require.NoError(t, err) - _, _, _, _, err = initHelper(t, keeper, ctx, v010CodeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d, "code_hash":"%s","label":"blabla", "msg":"%s"}}`, codeID, codeHash, `{\"counter\":{\"counter\":0, \"expires\":100}}`), true, true, defaultGasForTests) + _, _, _, _, err = initHelper(t, keeper, ctx, v010CodeID, walletA, nil, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d, "code_hash":"%s","label":"blabla", "msg":"%s"}}`, codeID, codeHash, `{\"counter\":{\"counter\":0, \"expires\":100}}`), true, true, defaultGasForTests) require.Contains(t, fmt.Sprintf("%+v", err), "got wrong counter on init") } @@ -454,7 +454,7 @@ func TestV010InitV1ContractFromExecuteWithErrResponse(t *testing.T) { v010CodeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") require.NoError(t, err) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, nil, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) queryRes, qErr := queryHelper(t, keeper, ctx, contractAddress, `{"get_contract_version":{}}`, true, false, math.MaxUint64) require.Empty(t, qErr) @@ -474,8 +474,8 @@ func TestV010ExecuteV1ContractFromInitWithErrResponse(t *testing.T) { v010CodeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") require.NoError(t, err) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"counter":{"counter":199, "expires":100}}`, true, true, defaultGasForTests) - _, _, _, _, err = initHelper(t, keeper, ctx, v010CodeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, contractAddress.String(), codeHash, `{\"increment\":{\"addition\": 0}}`), true, true, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"counter":{"counter":199, "expires":100}}`, true, true, defaultGasForTests) + _, _, _, _, err = initHelper(t, keeper, ctx, v010CodeID, walletA, nil, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, contractAddress.String(), codeHash, `{\"increment\":{\"addition\": 0}}`), true, true, defaultGasForTests) require.Contains(t, fmt.Sprintf("%+v", err), "got wrong counter on increment") } @@ -489,8 +489,8 @@ func TestV010ExecuteV1ContractFromExecuteWithErrResponse(t *testing.T) { v010CodeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") require.NoError(t, err) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"counter":{"counter":299, "expires":100}}`, true, true, defaultGasForTests) - _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"counter":{"counter":299, "expires":100}}`, true, true, defaultGasForTests) + _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, nil, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) _, _, _, _, _, err = execHelper(t, keeper, ctx, v010ContractAddress, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, contractAddress.String(), codeHash, `{\"increment\":{\"addition\": 0}}`), true, true, defaultGasForTests, 0) require.Contains(t, fmt.Sprintf("%+v", err), "got wrong counter on increment") @@ -505,8 +505,8 @@ func TestV010QueryV1ContractFromInitWithErrResponse(t *testing.T) { v010CodeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") require.NoError(t, err) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) - _, _, _, _, err = initHelper(t, keeper, ctx, v010CodeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, contractAddress.String(), codeHash, `{\"contract_error\":{\"error_type\":\"generic_err\"}}`), true, true, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + _, _, _, _, err = initHelper(t, keeper, ctx, v010CodeID, walletA, nil, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, contractAddress.String(), codeHash, `{\"contract_error\":{\"error_type\":\"generic_err\"}}`), true, true, defaultGasForTests) require.Contains(t, fmt.Sprintf("%+v", err), "la la 🤯") } @@ -519,8 +519,8 @@ func TestV010QueryV1ContractFromExecuteWithErrResponse(t *testing.T) { v010CodeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") require.NoError(t, err) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) - _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, nil, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) _, _, _, _, _, err = execHelper(t, keeper, ctx, v010ContractAddress, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, contractAddress.String(), codeHash, `{\"contract_error\":{\"error_type\":\"generic_err\"}}`), true, true, defaultGasForTests, 0) require.Contains(t, fmt.Sprintf("%+v", err), "la la 🤯") @@ -539,9 +539,9 @@ func TestV1SendsLogsMixedWithV010WithoutReply(t *testing.T) { require.NoError(t, err) v010CodeHash := hex.EncodeToString(codeInfo.CodeHash) - _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, nil, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) require.Empty(t, err) - _, _, v1ContractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + _, _, v1ContractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) require.Empty(t, err) nonce, ctx, _, logs, _, err := execHelper(t, keeper, ctx, v1ContractAddress, walletA, privKeyA, fmt.Sprintf(`{"add_attributes_from_v010":{"addr":"%s","code_hash":"%s", "id":0}}`, v010ContractAddress, v010CodeHash), true, true, defaultGasForTests, 0) require.Empty(t, err) @@ -601,9 +601,9 @@ func TestV1SendsLogsMixedWithV010WithReply(t *testing.T) { require.NoError(t, err) v010CodeHash := hex.EncodeToString(codeInfo.CodeHash) - _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, nil, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) require.Empty(t, err) - _, _, v1ContractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + _, _, v1ContractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) require.Empty(t, err) nonce, ctx, _, logs, _, err := execHelper(t, keeper, ctx, v1ContractAddress, walletA, privKeyA, fmt.Sprintf(`{"add_attributes_from_v010":{"addr":"%s","code_hash":"%s", "id":2500}}`, v010ContractAddress, v010CodeHash), true, true, defaultGasForTests, 0) require.Empty(t, err) @@ -683,9 +683,9 @@ func TestV010SendsLogsMixedWithV1(t *testing.T) { v010CodeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") require.NoError(t, err) - _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, nil, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) require.Empty(t, err) - _, _, v1ContractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + _, _, v1ContractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) require.Empty(t, err) nonce, ctx, _, logs, _, err := execHelper(t, keeper, ctx, v010ContractAddress, walletA, privKeyA, fmt.Sprintf(`{"add_mixed_events_and_attributes_from_v1":{"addr":"%s","code_hash":"%s"}}`, v1ContractAddress, v1CodeHash), true, true, defaultGasForTests, 0) require.Empty(t, err) diff --git a/x/compute/internal/keeper/staking_test.go b/x/compute/internal/keeper/staking_test.go index 260d5f5e4..3738758e6 100644 --- a/x/compute/internal/keeper/staking_test.go +++ b/x/compute/internal/keeper/staking_test.go @@ -135,7 +135,7 @@ func TestInitializeStaking(t *testing.T) { initBz, err = testEncrypt(t, keeper, ctx, nil, stakingID, initBz) require.NoError(t, err) - ctx = PrepareInitSignedTx(t, keeper, ctx, creator, creatorPrivKey, initBz, stakingID, nil) + ctx = PrepareInitSignedTx(t, keeper, ctx, creator, nil, creatorPrivKey, initBz, stakingID, nil) stakingAddr, _, err := keeper.Instantiate(ctx, stakingID, creator, nil, initBz, "staking derivates - DRV", nil, nil) require.NoError(t, err) require.NotEmpty(t, stakingAddr) @@ -156,7 +156,7 @@ func TestInitializeStaking(t *testing.T) { badBz, err := json.Marshal(&badInitMsg) require.NoError(t, err) - _, _, _, _, initErr := initHelper(t, keeper, ctx, stakingID, creator, creatorPrivKey, string(badBz), true, false, defaultGasForTests) + _, _, _, _, initErr := initHelper(t, keeper, ctx, stakingID, creator, nil, creatorPrivKey, string(badBz), true, false, defaultGasForTests) require.Error(t, initErr) require.Error(t, initErr.GenericErr) require.Equal(t, fmt.Sprintf("%s is not in the current validator set", sdk.ValAddress(bob).String()), initErr.GenericErr.Msg) @@ -229,7 +229,7 @@ func initializeStaking(t *testing.T) initInfo { initBz, err = testEncrypt(t, keeper, ctx, nil, stakingID, initBz) require.NoError(t, err) - ctx = PrepareInitSignedTx(t, keeper, ctx, creator, creatorPrivKey, initBz, stakingID, nil) + ctx = PrepareInitSignedTx(t, keeper, ctx, creator, nil, creatorPrivKey, initBz, stakingID, nil) stakingAddr, _, err := keeper.Instantiate(ctx, stakingID, creator, nil, initBz, "staking derivates - DRV", nil, nil) require.NoError(t, err) require.NotEmpty(t, stakingAddr) diff --git a/x/compute/internal/keeper/test_common.go b/x/compute/internal/keeper/test_common.go index d2cd39dbc..ed843d4af 100644 --- a/x/compute/internal/keeper/test_common.go +++ b/x/compute/internal/keeper/test_common.go @@ -676,7 +676,7 @@ func PrepareExecSignedTx(t *testing.T, keeper Keeper, ctx sdk.Context, sender sd return ctx.WithTxBytes(txBytes) } -func PrepareInitSignedTx(t *testing.T, keeper Keeper, ctx sdk.Context, creator sdk.AccAddress, privKey crypto.PrivKey, encMsg []byte, codeID uint64, funds sdk.Coins) sdk.Context { +func PrepareInitSignedTx(t *testing.T, keeper Keeper, ctx sdk.Context, creator, admin sdk.AccAddress, privKey crypto.PrivKey, encMsg []byte, codeID uint64, funds sdk.Coins) sdk.Context { creatorAcc, err := ante.GetSignerAcc(ctx, keeper.accountKeeper, creator) require.NoError(t, err) @@ -686,7 +686,7 @@ func PrepareInitSignedTx(t *testing.T, keeper Keeper, ctx sdk.Context, creator s Label: "demo contract 1", InitMsg: encMsg, InitFunds: funds, - Admin: creator.String(), + Admin: admin.String(), } newTx := NewTestTx(&initMsg, creatorAcc, privKey) From 35d47b7f0f06007a18dad8bbd744aed14d0e596b Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 13 Jun 2023 21:30:27 +0300 Subject: [PATCH 030/164] TestContractInfoAdmin & TestContractInfoNullAdmin --- .../keeper/secret_contracts_migrate_test.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/x/compute/internal/keeper/secret_contracts_migrate_test.go b/x/compute/internal/keeper/secret_contracts_migrate_test.go index b4a0bd8a7..102a60629 100644 --- a/x/compute/internal/keeper/secret_contracts_migrate_test.go +++ b/x/compute/internal/keeper/secret_contracts_migrate_test.go @@ -28,6 +28,24 @@ func TestMigrateContract(t *testing.T) { require.Empty(t, data) } +func TestContractInfoAdmin(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[migrateContractV1], sdk.NewCoins()) + + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"Nop":{}}`, true, true, defaultGasForTests) + + info := keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, walletA.String(), info.Admin) +} + +func TestContractInfoNullAdmin(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[migrateContractV1], sdk.NewCoins()) + + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"Nop":{}}`, true, true, defaultGasForTests) + + info := keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, sdk.AccAddress{}.String(), info.Admin) +} + func TestMigrateWithStorage(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[migrateContractV1], sdk.NewCoins()) From 9b946278a47d36ef2d09603109bec2d5b2597880 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 13 Jun 2023 21:33:32 +0300 Subject: [PATCH 031/164] Fix TestCheckGas --- x/compute/internal/keeper/secret_contracts_exec_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/compute/internal/keeper/secret_contracts_exec_test.go b/x/compute/internal/keeper/secret_contracts_exec_test.go index 67f689cc7..e8eb8b56f 100644 --- a/x/compute/internal/keeper/secret_contracts_exec_test.go +++ b/x/compute/internal/keeper/secret_contracts_exec_test.go @@ -2293,8 +2293,8 @@ func TestCheckGas(t *testing.T) { _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"Nop":{}}`, true, true, defaultGasForTests) require.Empty(t, initErr) - // 1069 is the sum of all the overhead that goes into a contract call beyond the base cost (reading keys, calculations, etc) - baseContractUsage := types.InstanceCost + 1069 + // 1031 is the sum of all the overhead that goes into a contract call beyond the base cost (reading/writing keys, calculations, etc) + baseContractUsage := types.InstanceCost + 1031 _, _, _, events, baseGasUsed, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"check_gas":{}}`, true, true, defaultGasForTests, 0) require.Empty(t, err) From 19cc11eca4779f5020dd5f400670404092e2fc31 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 13 Jun 2023 21:36:33 +0300 Subject: [PATCH 032/164] Fix TestConsumeExact --- x/compute/internal/keeper/secret_contracts_exec_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/compute/internal/keeper/secret_contracts_exec_test.go b/x/compute/internal/keeper/secret_contracts_exec_test.go index e8eb8b56f..22cdb908c 100644 --- a/x/compute/internal/keeper/secret_contracts_exec_test.go +++ b/x/compute/internal/keeper/secret_contracts_exec_test.go @@ -2313,7 +2313,7 @@ func TestConsumeExact(t *testing.T) { require.Empty(t, initErr) // not sure where the 16 extra gas comes vs the previous check_gas test, but it makes everything play nice, so.... - baseContractUsage := types.InstanceCost + 1053 - 16 + baseContractUsage := types.InstanceCost + 1031 - 16 for _, test := range []struct { description string From bc34a4d5bfa4c737a7e6d50b5dccf50c27173433 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 14 Jun 2023 09:20:45 +0300 Subject: [PATCH 033/164] lint --- x/registration/internal/types/reg_keys.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/registration/internal/types/reg_keys.go b/x/registration/internal/types/reg_keys.go index 90f9c7762..bd9e883bc 100644 --- a/x/registration/internal/types/reg_keys.go +++ b/x/registration/internal/types/reg_keys.go @@ -3,7 +3,7 @@ package types func GetApiKey() ([]byte, error) { - apiKeyFile, err := Asset("api_key.txt") //nolint:all + apiKeyFile, err := Asset("api_key.txt") if err != nil { return nil, err } @@ -12,7 +12,7 @@ func GetApiKey() ([]byte, error) { } func GetSpid() ([]byte, error) { - apiKeyFile, err := Asset("spid.txt") //nolint:all + apiKeyFile, err := Asset("spid.txt") if err != nil { return nil, err } From 7bd852a41992102340999003f130c0a9b6c2a38d Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 14 Jun 2023 11:49:44 +0300 Subject: [PATCH 034/164] Rename ContractInfo to contract_info --- proto/secret/compute/v1beta1/query.proto | 4 +- x/compute/internal/types/query.pb.go | 158 +++++++++++------------ 2 files changed, 81 insertions(+), 81 deletions(-) diff --git a/proto/secret/compute/v1beta1/query.proto b/proto/secret/compute/v1beta1/query.proto index 549942d5d..a82240683 100644 --- a/proto/secret/compute/v1beta1/query.proto +++ b/proto/secret/compute/v1beta1/query.proto @@ -90,7 +90,7 @@ message QuerySecretContractResponse { bytes data = 1; } message QueryContractInfoResponse { // contract_address is the bech32 human readable address of the contract string contract_address = 1; - ContractInfo ContractInfo = 2 + ContractInfo contract_info = 2 [ (gogoproto.embed) = true, (gogoproto.jsontag) = "" ]; } @@ -98,7 +98,7 @@ message QueryContractInfoResponse { message ContractInfoWithAddress { // contract_address is the bech32 human readable address of the contract string contract_address = 1; - ContractInfo ContractInfo = 2 + ContractInfo contract_info = 2 [ (gogoproto.embed) = true, (gogoproto.jsontag) = "" ]; } diff --git a/x/compute/internal/types/query.pb.go b/x/compute/internal/types/query.pb.go index c61a84011..4036fc171 100644 --- a/x/compute/internal/types/query.pb.go +++ b/x/compute/internal/types/query.pb.go @@ -225,7 +225,7 @@ var xxx_messageInfo_QuerySecretContractResponse proto.InternalMessageInfo type QueryContractInfoResponse struct { // contract_address is the bech32 human readable address of the contract ContractAddress string `protobuf:"bytes,1,opt,name=contract_address,json=contractAddress,proto3" json:"contract_address,omitempty"` - *ContractInfo `protobuf:"bytes,2,opt,name=ContractInfo,proto3,embedded=ContractInfo" json:""` + *ContractInfo `protobuf:"bytes,2,opt,name=contract_info,json=contractInfo,proto3,embedded=contract_info" json:""` } func (m *QueryContractInfoResponse) Reset() { *m = QueryContractInfoResponse{} } @@ -265,7 +265,7 @@ var xxx_messageInfo_QueryContractInfoResponse proto.InternalMessageInfo type ContractInfoWithAddress struct { // contract_address is the bech32 human readable address of the contract ContractAddress string `protobuf:"bytes,1,opt,name=contract_address,json=contractAddress,proto3" json:"contract_address,omitempty"` - *ContractInfo `protobuf:"bytes,2,opt,name=ContractInfo,proto3,embedded=ContractInfo" json:""` + *ContractInfo `protobuf:"bytes,2,opt,name=contract_info,json=contractInfo,proto3,embedded=contract_info" json:""` } func (m *ContractInfoWithAddress) Reset() { *m = ContractInfoWithAddress{} } @@ -755,83 +755,83 @@ func init() { var fileDescriptor_7735281c5fa969d4 = []byte{ // 1245 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x57, 0xcf, 0x6f, 0x1b, 0xc5, - 0x17, 0xf7, 0xb4, 0x4e, 0xd3, 0x4c, 0xd2, 0x24, 0x9d, 0x6f, 0x9a, 0xba, 0x4e, 0xbf, 0x4e, 0xbb, - 0x14, 0xf2, 0xab, 0x78, 0x6b, 0x27, 0x14, 0xa9, 0xe2, 0x92, 0xa4, 0x91, 0x1a, 0x14, 0x0a, 0xb8, - 0x07, 0x24, 0x54, 0x64, 0x8d, 0xd7, 0x13, 0x7b, 0x55, 0x67, 0xc7, 0xdd, 0x19, 0x27, 0xb1, 0x50, - 0x38, 0x70, 0xe2, 0x88, 0x04, 0x48, 0x08, 0x2e, 0x9c, 0xa0, 0xe2, 0x80, 0xc4, 0x95, 0xbf, 0x20, - 0x07, 0x0e, 0x91, 0xb8, 0x70, 0xaa, 0x20, 0xe1, 0x80, 0xb8, 0x73, 0x47, 0xf3, 0x66, 0x76, 0xb3, - 0xb6, 0xd7, 0xb1, 0x5d, 0x0e, 0xdc, 0x76, 0x66, 0xde, 0xbc, 0xcf, 0x67, 0x3e, 0xef, 0xcd, 0x7b, - 0xb3, 0xd8, 0x12, 0xcc, 0xf1, 0x99, 0xb4, 0x1d, 0xbe, 0x53, 0x6f, 0x48, 0x66, 0xef, 0xe6, 0x4a, - 0x4c, 0xd2, 0x9c, 0xfd, 0xb4, 0xc1, 0xfc, 0x66, 0xb6, 0xee, 0x73, 0xc9, 0xc9, 0xb4, 0xb6, 0xc9, - 0x1a, 0x9b, 0xac, 0xb1, 0x49, 0x4f, 0x55, 0x78, 0x85, 0x83, 0x89, 0xad, 0xbe, 0xb4, 0x75, 0xba, - 0x9b, 0x47, 0xd9, 0xac, 0x33, 0x61, 0x6c, 0x66, 0x2a, 0x9c, 0x57, 0x6a, 0xcc, 0x86, 0x51, 0xa9, - 0xb1, 0x6d, 0xb3, 0x9d, 0xba, 0x34, 0x70, 0xe9, 0xeb, 0x66, 0x91, 0xd6, 0x5d, 0x9b, 0x7a, 0x1e, - 0x97, 0x54, 0xba, 0xdc, 0x0b, 0xb6, 0xbe, 0xe4, 0x70, 0xb1, 0xc3, 0x85, 0x5d, 0xa2, 0x82, 0xd9, - 0xb4, 0xe4, 0xb8, 0x21, 0x80, 0x1a, 0x18, 0xa3, 0xc5, 0xa8, 0x11, 0x1c, 0x25, 0xb4, 0xaa, 0xd3, - 0x8a, 0xeb, 0x81, 0x47, 0x6d, 0x6b, 0x7d, 0x80, 0xd3, 0xef, 0x2a, 0x8b, 0x47, 0x40, 0x7b, 0x9d, - 0x7b, 0xd2, 0xa7, 0x8e, 0x2c, 0xb0, 0xa7, 0x0d, 0x26, 0x24, 0x59, 0xc0, 0x93, 0x8e, 0x99, 0x2a, - 0xd2, 0x72, 0xd9, 0x67, 0x42, 0xa4, 0xd0, 0x0d, 0x34, 0x3f, 0x52, 0x98, 0x08, 0xe6, 0x57, 0xf5, - 0x34, 0x99, 0xc2, 0x43, 0x00, 0x95, 0x3a, 0x77, 0x03, 0xcd, 0x8f, 0x15, 0xf4, 0xc0, 0x5a, 0xc2, - 0xff, 0x03, 0xf7, 0x6b, 0xcd, 0x2d, 0x5a, 0x62, 0xb5, 0xc0, 0xef, 0x14, 0x1e, 0xaa, 0xa9, 0xb1, - 0x71, 0xa6, 0x07, 0xd6, 0x9b, 0xf8, 0xff, 0xc6, 0x78, 0xbd, 0xd5, 0xf9, 0xe0, 0x74, 0x2c, 0x1b, - 0x4f, 0x85, 0xbe, 0xca, 0x6c, 0xb3, 0x1c, 0xb8, 0xb8, 0x8a, 0x87, 0x1d, 0x5e, 0x66, 0x45, 0xb7, - 0x0c, 0x3b, 0x93, 0x85, 0x0b, 0x0e, 0xac, 0x5b, 0x39, 0x3c, 0x13, 0x2b, 0x84, 0xa8, 0x73, 0x4f, - 0x30, 0x42, 0x70, 0xb2, 0x4c, 0x25, 0x85, 0x4d, 0x63, 0x05, 0xf8, 0xb6, 0xbe, 0x42, 0xf8, 0x1a, - 0xec, 0x09, 0xac, 0x37, 0xbd, 0x6d, 0x1e, 0xee, 0x18, 0x40, 0xbb, 0x02, 0x1e, 0x8b, 0xba, 0x00, - 0x09, 0x47, 0xf3, 0xb7, 0xb2, 0xf1, 0x99, 0x97, 0x8d, 0xda, 0xae, 0x5d, 0x3c, 0x7a, 0x3e, 0x8b, - 0xfe, 0x7a, 0x3e, 0x9b, 0x28, 0xb4, 0xf8, 0xb0, 0xbe, 0x44, 0xf8, 0x6a, 0x74, 0xe2, 0x3d, 0x57, - 0x56, 0x03, 0xbc, 0xff, 0x98, 0xda, 0x47, 0x38, 0xd3, 0x22, 0x9b, 0x38, 0x0d, 0x92, 0xd1, 0xee, - 0x31, 0x1e, 0x0f, 0x09, 0xba, 0xde, 0x36, 0x57, 0xf4, 0xce, 0xcf, 0x8f, 0xe6, 0xed, 0x7e, 0x70, - 0x23, 0x27, 0x5d, 0x4b, 0x1e, 0x2a, 0xf8, 0x4b, 0x4e, 0x64, 0x59, 0x58, 0x9f, 0x23, 0x3c, 0x09, - 0x80, 0xd1, 0x70, 0x75, 0x4b, 0x0c, 0x92, 0xc2, 0xc3, 0x8e, 0xcf, 0xa8, 0xe4, 0x3e, 0x1c, 0x7e, - 0xa4, 0x10, 0x0c, 0xc9, 0x0c, 0x1e, 0x81, 0x2d, 0x55, 0x2a, 0xaa, 0xa9, 0xf3, 0xb0, 0x76, 0x51, - 0x4d, 0x3c, 0xa0, 0xa2, 0x4a, 0xa6, 0xf1, 0x05, 0xc1, 0x1b, 0xbe, 0xc3, 0x52, 0x49, 0x58, 0x31, - 0x23, 0xe5, 0xae, 0xd4, 0x70, 0x6b, 0x65, 0xe6, 0xa7, 0x86, 0xb4, 0x3b, 0x33, 0xb4, 0xf6, 0xf1, - 0x65, 0x23, 0x4b, 0x99, 0x85, 0xb4, 0xde, 0x36, 0x18, 0x4a, 0x05, 0x20, 0x36, 0x9a, 0x9f, 0xef, - 0x2e, 0x42, 0xeb, 0x99, 0x22, 0x01, 0x00, 0x5e, 0x6a, 0x4d, 0x25, 0xf2, 0x1e, 0x15, 0x3b, 0xe6, - 0x9a, 0xc2, 0xb7, 0xe5, 0x60, 0x12, 0x22, 0x8b, 0x10, 0xfa, 0x2d, 0x8c, 0x43, 0xe8, 0x20, 0x00, - 0xfd, 0x63, 0x6b, 0xe5, 0x47, 0x02, 0x5c, 0x61, 0x6d, 0xe2, 0xeb, 0x2d, 0x51, 0x0f, 0xef, 0xf6, - 0xc0, 0xf7, 0xc5, 0xca, 0x9b, 0xa2, 0x15, 0xb8, 0x32, 0xb5, 0xc5, 0x38, 0x8a, 0x2f, 0x2e, 0x2b, - 0xf8, 0x4a, 0x78, 0x46, 0x15, 0xa0, 0xd0, 0xbc, 0x25, 0x8a, 0xa8, 0x35, 0x8a, 0xd6, 0x17, 0x08, - 0x4f, 0xdc, 0x67, 0x8e, 0xdf, 0xac, 0x4b, 0x56, 0x5e, 0xf5, 0xc4, 0x1e, 0xf3, 0x95, 0x82, 0xaa, - 0x9a, 0x1b, 0x5b, 0xf8, 0x56, 0x98, 0xae, 0x57, 0x6f, 0x48, 0x93, 0x22, 0x7a, 0x40, 0x66, 0xf1, - 0x28, 0x6f, 0xc8, 0x7a, 0x43, 0x16, 0xa1, 0x76, 0xe8, 0x14, 0xc1, 0x7a, 0xea, 0x3e, 0x95, 0x94, - 0xe4, 0xf0, 0x95, 0x88, 0x41, 0x91, 0x8a, 0xa2, 0x90, 0xbe, 0xeb, 0x55, 0x4c, 0xce, 0x90, 0x53, - 0xd3, 0x55, 0xf1, 0x08, 0x56, 0xee, 0x25, 0xff, 0xfc, 0x66, 0x36, 0x61, 0xfd, 0x8d, 0xf0, 0x64, - 0x1b, 0x2f, 0x41, 0x56, 0xf1, 0x30, 0xd5, 0x9f, 0x26, 0x5a, 0x73, 0xdd, 0xa2, 0xd5, 0xb6, 0xb5, - 0x10, 0xec, 0x23, 0x5b, 0x21, 0xe3, 0x1a, 0xaf, 0x88, 0xd4, 0x39, 0x70, 0xf3, 0x72, 0x56, 0x37, - 0x94, 0xac, 0x6a, 0x28, 0x59, 0x68, 0x34, 0x81, 0x23, 0x4d, 0x6a, 0x63, 0x97, 0x79, 0xd2, 0x44, - 0xdc, 0x1c, 0x6f, 0x8b, 0x57, 0x04, 0xb9, 0x89, 0xc7, 0x8c, 0x37, 0xe6, 0xfb, 0xdc, 0x37, 0x02, - 0x18, 0x84, 0x0d, 0x35, 0x45, 0xe6, 0xf0, 0x44, 0xbd, 0x46, 0x5d, 0x4f, 0xb2, 0xfd, 0xc0, 0x4a, - 0x9f, 0x7d, 0x3c, 0x9c, 0x06, 0x43, 0x73, 0xee, 0x87, 0xa6, 0x4a, 0x07, 0x91, 0x7f, 0xe0, 0x0a, - 0xc9, 0xfd, 0xe6, 0xe0, 0x0d, 0xc2, 0xf8, 0xdb, 0x6d, 0x4b, 0xca, 0xd0, 0x9f, 0x49, 0x8e, 0x77, - 0xf0, 0x30, 0xf3, 0xa4, 0xef, 0xb2, 0x40, 0xd2, 0x3b, 0xbd, 0x2a, 0x10, 0xe4, 0x97, 0xf6, 0xb2, - 0xe1, 0x49, 0xbf, 0x69, 0x64, 0x09, 0xdc, 0x68, 0xdc, 0xfc, 0xd7, 0x97, 0xf0, 0x10, 0x00, 0x93, - 0xef, 0x51, 0x6b, 0x85, 0x25, 0xaf, 0x75, 0x43, 0x38, 0xb3, 0x37, 0xa6, 0x73, 0x67, 0x6e, 0x8b, - 0xeb, 0x50, 0xd6, 0x9d, 0x8f, 0x7f, 0xf9, 0xe3, 0xb3, 0x73, 0x8b, 0x64, 0xbe, 0xe3, 0xb5, 0xa2, - 0xae, 0xbc, 0xfd, 0x61, 0xbb, 0x94, 0x07, 0xe4, 0x3b, 0x84, 0x2f, 0x77, 0x54, 0x6d, 0x72, 0xbb, - 0x27, 0xe3, 0x48, 0x07, 0x4e, 0xdf, 0xed, 0x8b, 0x68, 0x47, 0x4f, 0xb0, 0x6e, 0x03, 0xdb, 0x57, - 0xc8, 0xad, 0x0e, 0xb6, 0x01, 0x4f, 0xa1, 0x28, 0x43, 0x09, 0x3f, 0x20, 0x3f, 0x22, 0xf3, 0xf2, - 0x68, 0xed, 0xe7, 0x24, 0x7f, 0x26, 0x7a, 0xec, 0x2b, 0x28, 0xbd, 0x3c, 0xd0, 0x1e, 0x43, 0x37, - 0x07, 0x74, 0x97, 0xc8, 0x42, 0xfc, 0xe3, 0x32, 0x4e, 0xdd, 0x4f, 0x10, 0x4e, 0xaa, 0x43, 0x0f, - 0x28, 0xe8, 0x42, 0x0f, 0x41, 0x4f, 0xbb, 0x89, 0x35, 0x07, 0xa4, 0x6e, 0x92, 0xd9, 0x18, 0x0d, - 0xcb, 0x2c, 0x22, 0xdf, 0x13, 0x3c, 0x04, 0xcd, 0x80, 0x4c, 0x67, 0xf5, 0x7b, 0x34, 0x1b, 0x3c, - 0x56, 0xb3, 0x1b, 0xea, 0xb1, 0x9a, 0x5e, 0xec, 0x09, 0x1a, 0x56, 0x76, 0x2b, 0x03, 0xa8, 0x29, - 0x32, 0x1d, 0x8b, 0x2a, 0xc8, 0xcf, 0x08, 0x5f, 0x0b, 0xca, 0x72, 0x47, 0x7e, 0xbf, 0xe8, 0x7d, - 0x78, 0xb5, 0x27, 0xc1, 0x68, 0x17, 0xb0, 0x36, 0x81, 0xe3, 0x3a, 0x59, 0x8d, 0xe5, 0x08, 0xcd, - 0xc1, 0x2e, 0x35, 0x8b, 0xed, 0x41, 0x8b, 0x0b, 0xe3, 0x33, 0xf3, 0xbc, 0x08, 0x8e, 0xf3, 0x02, - 0x77, 0x64, 0x40, 0xf2, 0xaf, 0x03, 0xf9, 0x1c, 0xb1, 0x7b, 0x91, 0x87, 0xe8, 0x46, 0xc2, 0xfc, - 0x03, 0xc2, 0xe3, 0xd0, 0x3c, 0xd7, 0x9a, 0xff, 0x52, 0xee, 0x7c, 0x5f, 0xb7, 0xba, 0xa5, 0x51, - 0x9f, 0x71, 0x45, 0xa0, 0x65, 0xc7, 0x69, 0xfb, 0x2d, 0xc2, 0xe3, 0xc1, 0xdb, 0x4e, 0xff, 0x52, - 0x90, 0xa5, 0x1e, 0x84, 0xa3, 0x3f, 0x1e, 0xe9, 0x95, 0xbe, 0x68, 0xb6, 0x3d, 0x4d, 0xce, 0x20, - 0xda, 0x99, 0x0f, 0x40, 0xfd, 0x80, 0xfc, 0x84, 0xf0, 0x44, 0x5b, 0x53, 0x21, 0xcb, 0x7d, 0x81, - 0xb7, 0xb6, 0xb4, 0x3e, 0x19, 0xb7, 0xf5, 0x2d, 0xeb, 0x0d, 0x60, 0x7c, 0x97, 0xac, 0x74, 0x67, - 0x5c, 0xd5, 0x5b, 0x62, 0x54, 0x5e, 0x7b, 0x7c, 0xf8, 0x7b, 0x26, 0xf1, 0xec, 0x38, 0x83, 0x0e, - 0x8f, 0x33, 0xe8, 0xe8, 0x38, 0x83, 0x7e, 0x3b, 0xce, 0xa0, 0x4f, 0x4f, 0x32, 0x89, 0xa3, 0x93, - 0x4c, 0xe2, 0xd7, 0x93, 0x4c, 0xe2, 0xfd, 0x7b, 0x15, 0x57, 0x56, 0x1b, 0x25, 0x45, 0xca, 0x16, - 0x8e, 0x2f, 0x6b, 0xb4, 0x24, 0x6c, 0x5d, 0x09, 0x1f, 0x32, 0xb9, 0xc7, 0xfd, 0x27, 0xf6, 0x7e, - 0x08, 0xad, 0xda, 0xb8, 0xef, 0xd1, 0x9a, 0xfe, 0x09, 0x2e, 0x5d, 0x80, 0x52, 0xb2, 0xfc, 0x4f, - 0x00, 0x00, 0x00, 0xff, 0xff, 0x58, 0xe3, 0xa9, 0xe7, 0x7d, 0x0f, 0x00, 0x00, + 0x17, 0xf7, 0xa4, 0x4e, 0xd2, 0x4c, 0x7e, 0x76, 0xbe, 0x69, 0xea, 0x3a, 0xfd, 0x3a, 0xed, 0x52, + 0xc8, 0xaf, 0xe2, 0xad, 0x9d, 0x50, 0xa4, 0x8a, 0x4b, 0x92, 0x46, 0x6a, 0x50, 0x28, 0xe0, 0x1c, + 0x90, 0x50, 0x91, 0x35, 0x5e, 0x4f, 0xec, 0x55, 0x9d, 0x9d, 0xed, 0xce, 0x38, 0x89, 0x85, 0xc2, + 0x81, 0x13, 0x47, 0x24, 0xe0, 0x80, 0x7a, 0xe1, 0x04, 0x15, 0x07, 0x24, 0xae, 0xfc, 0x05, 0x39, + 0x70, 0x88, 0xc4, 0x85, 0x53, 0x05, 0x09, 0x07, 0xc4, 0x9d, 0x3b, 0xda, 0x37, 0xb3, 0x9b, 0xb5, + 0xbd, 0x8e, 0xed, 0x72, 0xe0, 0xb6, 0x33, 0xf3, 0xe6, 0x7d, 0x3e, 0xf3, 0x79, 0x6f, 0xde, 0x9b, + 0xc5, 0x86, 0x60, 0x96, 0xc7, 0xa4, 0x69, 0xf1, 0x3d, 0xb7, 0x2e, 0x99, 0xb9, 0x9f, 0x2b, 0x31, + 0x49, 0x73, 0xe6, 0xd3, 0x3a, 0xf3, 0x1a, 0x59, 0xd7, 0xe3, 0x92, 0x93, 0x19, 0x65, 0x93, 0xd5, + 0x36, 0x59, 0x6d, 0x93, 0x9e, 0xae, 0xf0, 0x0a, 0x07, 0x13, 0xd3, 0xff, 0x52, 0xd6, 0xe9, 0x4e, + 0x1e, 0x65, 0xc3, 0x65, 0x42, 0xdb, 0xcc, 0x56, 0x38, 0xaf, 0xd4, 0x98, 0x09, 0xa3, 0x52, 0x7d, + 0xd7, 0x64, 0x7b, 0xae, 0xd4, 0x70, 0xe9, 0x1b, 0x7a, 0x91, 0xba, 0xb6, 0x49, 0x1d, 0x87, 0x4b, + 0x2a, 0x6d, 0xee, 0x04, 0x5b, 0x5f, 0xb1, 0xb8, 0xd8, 0xe3, 0xc2, 0x2c, 0x51, 0xc1, 0x4c, 0x5a, + 0xb2, 0xec, 0x10, 0xc0, 0x1f, 0x68, 0xa3, 0xa5, 0xa8, 0x11, 0x1c, 0x25, 0xb4, 0x72, 0x69, 0xc5, + 0x76, 0xc0, 0xa3, 0xb2, 0x35, 0x3e, 0xc2, 0xe9, 0xf7, 0x7d, 0x8b, 0x1d, 0xa0, 0xbd, 0xc1, 0x1d, + 0xe9, 0x51, 0x4b, 0x16, 0xd8, 0xd3, 0x3a, 0x13, 0x92, 0x2c, 0xe2, 0x29, 0x4b, 0x4f, 0x15, 0x69, + 0xb9, 0xec, 0x31, 0x21, 0x52, 0xe8, 0x26, 0x5a, 0x18, 0x29, 0x4c, 0x06, 0xf3, 0x6b, 0x6a, 0x9a, + 0x4c, 0xe3, 0x41, 0x80, 0x4a, 0x0d, 0xdc, 0x44, 0x0b, 0x63, 0x05, 0x35, 0x30, 0x96, 0xf1, 0xff, + 0xc0, 0xfd, 0x7a, 0x63, 0x9b, 0x96, 0x58, 0x2d, 0xf0, 0x3b, 0x8d, 0x07, 0x6b, 0xfe, 0x58, 0x3b, + 0x53, 0x03, 0xe3, 0x6d, 0xfc, 0x7f, 0x6d, 0xbc, 0xd1, 0xec, 0xbc, 0x7f, 0x3a, 0x86, 0x89, 0xa7, + 0x43, 0x5f, 0x65, 0xb6, 0x55, 0x0e, 0x5c, 0x5c, 0xc3, 0xc3, 0x16, 0x2f, 0xb3, 0xa2, 0x5d, 0x86, + 0x9d, 0xc9, 0xc2, 0x90, 0x05, 0xeb, 0x46, 0x0e, 0xcf, 0xc6, 0x0a, 0x21, 0x5c, 0xee, 0x08, 0x46, + 0x08, 0x4e, 0x96, 0xa9, 0xa4, 0xb0, 0x69, 0xac, 0x00, 0xdf, 0xc6, 0x33, 0x84, 0xaf, 0xc3, 0x9e, + 0xc0, 0x7a, 0xcb, 0xd9, 0xe5, 0xe1, 0x8e, 0x3e, 0xb4, 0xdb, 0xc1, 0xe3, 0xa1, 0xa9, 0xed, 0xec, + 0x72, 0xd0, 0x70, 0x34, 0x7f, 0x3b, 0x1b, 0x9f, 0x7a, 0xd9, 0x28, 0xde, 0xfa, 0xe5, 0x93, 0x17, + 0x73, 0xe8, 0xaf, 0x17, 0x73, 0x89, 0xc2, 0x98, 0x15, 0x99, 0x37, 0xbe, 0x46, 0xf8, 0x5a, 0xd4, + 0xf0, 0x03, 0x5b, 0x56, 0x03, 0xc0, 0xff, 0x9a, 0xdb, 0x27, 0x38, 0xd3, 0x24, 0x9c, 0x38, 0x0f, + 0x93, 0x56, 0xef, 0x31, 0x9e, 0x68, 0x82, 0xf5, 0xf9, 0x5d, 0x5a, 0x18, 0xcd, 0x9b, 0xbd, 0xe0, + 0x46, 0x8e, 0xba, 0x9e, 0x3c, 0xf6, 0xe1, 0xc7, 0xa3, 0xf0, 0xc2, 0xf8, 0x12, 0xe1, 0x29, 0x00, + 0x8c, 0x06, 0xac, 0x53, 0x6a, 0x90, 0x14, 0x1e, 0xb6, 0x3c, 0x46, 0x25, 0xf7, 0xe0, 0xf0, 0x23, + 0x85, 0x60, 0x48, 0x66, 0xf1, 0x08, 0x6c, 0xa9, 0x52, 0x51, 0x4d, 0x5d, 0x82, 0xb5, 0xcb, 0xfe, + 0xc4, 0x43, 0x2a, 0xaa, 0x64, 0x06, 0x0f, 0x09, 0x5e, 0xf7, 0x2c, 0x96, 0x4a, 0xc2, 0x8a, 0x1e, + 0xf9, 0xee, 0x4a, 0x75, 0xbb, 0x56, 0x66, 0x5e, 0x6a, 0x50, 0xb9, 0xd3, 0x43, 0xe3, 0x10, 0x5f, + 0xd1, 0xb2, 0x94, 0x59, 0x48, 0xeb, 0x5d, 0x8d, 0x01, 0xe2, 0x23, 0x10, 0x7f, 0xa1, 0xb3, 0x08, + 0xcd, 0x67, 0x8a, 0x04, 0x00, 0x78, 0xf9, 0x6b, 0x7e, 0x2a, 0x1f, 0x50, 0xb1, 0xa7, 0x2f, 0x2a, + 0x7c, 0x1b, 0x16, 0x26, 0x21, 0xb2, 0x08, 0xa1, 0xdf, 0xc1, 0x38, 0x84, 0x0e, 0x02, 0xd0, 0x3b, + 0xb6, 0x52, 0x7e, 0x24, 0xc0, 0x15, 0xc6, 0x16, 0xbe, 0xd1, 0x14, 0xf5, 0xf0, 0x76, 0xf7, 0x7d, + 0x63, 0x8c, 0xbc, 0x2e, 0x5b, 0x81, 0x2b, 0x5d, 0x5d, 0xb4, 0xa3, 0xf8, 0xf2, 0xb2, 0x8a, 0xaf, + 0x86, 0x67, 0xf4, 0x03, 0x14, 0x9a, 0x37, 0x45, 0x11, 0x35, 0x47, 0xd1, 0xf8, 0x0a, 0xe1, 0xc9, + 0x07, 0xcc, 0xf2, 0x1a, 0xae, 0x64, 0xe5, 0x35, 0x47, 0x1c, 0x30, 0xcf, 0x57, 0xd0, 0xaf, 0xe7, + 0xda, 0x16, 0xbe, 0x7d, 0x4c, 0xdb, 0x71, 0xeb, 0x52, 0xa7, 0x88, 0x1a, 0x90, 0x39, 0x3c, 0xca, + 0xeb, 0xd2, 0xad, 0xcb, 0x22, 0x54, 0x0f, 0x95, 0x22, 0x58, 0x4d, 0x3d, 0xa0, 0x92, 0x92, 0x1c, + 0xbe, 0x1a, 0x31, 0x28, 0x52, 0x51, 0x14, 0xd2, 0xb3, 0x9d, 0x8a, 0xce, 0x19, 0x72, 0x6e, 0xba, + 0x26, 0x76, 0x60, 0xe5, 0x7e, 0xf2, 0xcf, 0x6f, 0xe6, 0x12, 0xc6, 0xdf, 0x08, 0x4f, 0xb5, 0xf0, + 0x12, 0x64, 0x0d, 0x0f, 0x53, 0xf5, 0xa9, 0xa3, 0x35, 0xdf, 0x29, 0x5a, 0x2d, 0x5b, 0x0b, 0xc1, + 0x3e, 0xb2, 0x1d, 0x32, 0xae, 0xf1, 0x8a, 0x48, 0x0d, 0x80, 0x9b, 0x57, 0xb3, 0xaa, 0xa5, 0x64, + 0xfd, 0x96, 0x92, 0x85, 0x56, 0x13, 0x38, 0x52, 0xa4, 0x36, 0xf7, 0x99, 0x23, 0x75, 0xc4, 0xf5, + 0xf1, 0xb6, 0x79, 0x45, 0x90, 0x5b, 0x78, 0x4c, 0x7b, 0x63, 0x9e, 0xc7, 0x3d, 0x2d, 0x80, 0x46, + 0xd8, 0xf4, 0xa7, 0xc8, 0x3c, 0x9e, 0x74, 0x6b, 0xd4, 0x76, 0x24, 0x3b, 0x0c, 0xac, 0xd4, 0xd9, + 0x27, 0xc2, 0x69, 0x30, 0xd4, 0xe7, 0x7e, 0xa4, 0xeb, 0x74, 0x10, 0xf9, 0x87, 0xb6, 0x90, 0xdc, + 0x6b, 0xf4, 0xdf, 0x22, 0xb4, 0xbf, 0xfd, 0x96, 0xa4, 0x0c, 0xfd, 0xe9, 0xe4, 0x78, 0x0f, 0x0f, + 0x33, 0x47, 0x7a, 0x36, 0x0b, 0x24, 0xbd, 0xdb, 0xad, 0x02, 0x41, 0x7e, 0x29, 0x2f, 0x9b, 0x8e, + 0xf4, 0x1a, 0x5a, 0x96, 0xc0, 0x8d, 0xc2, 0xcd, 0x3f, 0x1b, 0xc7, 0x83, 0x00, 0x4c, 0xbe, 0x47, + 0x78, 0x2c, 0x5a, 0xbd, 0xc8, 0x1b, 0x9d, 0x10, 0x2e, 0xec, 0x8e, 0xe9, 0xdc, 0x85, 0xdb, 0xe2, + 0x7a, 0x94, 0x71, 0xf7, 0xd3, 0x5f, 0xfe, 0xf8, 0x62, 0x60, 0x89, 0x2c, 0xb4, 0xbd, 0x57, 0xfc, + 0x2b, 0x6f, 0x7e, 0xdc, 0x2a, 0xe5, 0x11, 0xf9, 0x0e, 0xe1, 0x2b, 0x6d, 0x55, 0x9b, 0xdc, 0xe9, + 0xca, 0x38, 0xd2, 0x83, 0xd3, 0xf7, 0x7a, 0x22, 0xda, 0xd6, 0x13, 0x8c, 0x3b, 0xc0, 0xf6, 0x35, + 0x72, 0xbb, 0x8d, 0x6d, 0xc0, 0x53, 0xf8, 0x94, 0xa1, 0x84, 0x1f, 0x91, 0x1f, 0x91, 0x7e, 0x7b, + 0x34, 0x77, 0x74, 0x92, 0xbf, 0x10, 0x3d, 0xf6, 0x1d, 0x94, 0x5e, 0xe9, 0x6b, 0x8f, 0xa6, 0x9b, + 0x03, 0xba, 0xcb, 0x64, 0x31, 0xfe, 0x79, 0x19, 0xa7, 0xee, 0x67, 0x08, 0x27, 0xfd, 0x43, 0xf7, + 0x29, 0xe8, 0x62, 0x17, 0x41, 0xcf, 0xbb, 0x89, 0x31, 0x0f, 0xa4, 0x6e, 0x91, 0xb9, 0x18, 0x0d, + 0xcb, 0x2c, 0x22, 0xdf, 0x13, 0x3c, 0x08, 0xcd, 0x80, 0xcc, 0x64, 0xd5, 0x8b, 0x34, 0x1b, 0x3c, + 0x57, 0xb3, 0x9b, 0xfe, 0x73, 0x35, 0xbd, 0xd4, 0x15, 0x34, 0xac, 0xec, 0x46, 0x06, 0x50, 0x53, + 0x64, 0x26, 0x16, 0x55, 0x90, 0x9f, 0x11, 0xbe, 0x1e, 0x94, 0xe5, 0xb6, 0xfc, 0x7e, 0xd9, 0xfb, + 0xf0, 0x7a, 0x57, 0x82, 0xd1, 0x2e, 0x60, 0x6c, 0x01, 0xc7, 0x0d, 0xb2, 0x16, 0xcb, 0x11, 0x9a, + 0x83, 0x59, 0x6a, 0x14, 0x5b, 0x83, 0x16, 0x17, 0xc6, 0xe7, 0xfa, 0x79, 0x11, 0x1c, 0xe7, 0x25, + 0xee, 0x48, 0x9f, 0xe4, 0xdf, 0x04, 0xf2, 0x39, 0x62, 0x76, 0x23, 0x0f, 0xd1, 0x8d, 0x84, 0xf9, + 0x07, 0x84, 0x27, 0xa0, 0x79, 0xae, 0x37, 0xfe, 0xa5, 0xdc, 0xf9, 0x9e, 0x6e, 0x75, 0x53, 0xa3, + 0xbe, 0xe0, 0x8a, 0x40, 0xcb, 0x8e, 0xd3, 0xf6, 0x5b, 0x84, 0x27, 0x82, 0xb7, 0x9d, 0xfa, 0xa9, + 0x20, 0xcb, 0x5d, 0x08, 0x47, 0x7f, 0x3d, 0xd2, 0xab, 0x3d, 0xd1, 0x6c, 0x79, 0x9a, 0x5c, 0x40, + 0xb4, 0x3d, 0x1f, 0x80, 0xfa, 0x11, 0xf9, 0x09, 0xe1, 0xc9, 0x96, 0xa6, 0x42, 0x56, 0x7a, 0x02, + 0x6f, 0x6e, 0x69, 0x3d, 0x32, 0x6e, 0xe9, 0x5b, 0xc6, 0x5b, 0xc0, 0xf8, 0x1e, 0x59, 0xed, 0xcc, + 0xb8, 0xaa, 0xb6, 0xc4, 0xa8, 0xbc, 0xfe, 0xf8, 0xf8, 0xf7, 0x4c, 0xe2, 0xf9, 0x69, 0x06, 0x1d, + 0x9f, 0x66, 0xd0, 0xc9, 0x69, 0x06, 0xfd, 0x76, 0x9a, 0x41, 0x9f, 0x9f, 0x65, 0x12, 0x27, 0x67, + 0x99, 0xc4, 0xaf, 0x67, 0x99, 0xc4, 0x87, 0xf7, 0x2b, 0xb6, 0xac, 0xd6, 0x4b, 0x3e, 0x29, 0x53, + 0x58, 0x9e, 0xac, 0xd1, 0x92, 0x30, 0x55, 0x25, 0x7c, 0xc4, 0xe4, 0x01, 0xf7, 0x9e, 0x98, 0x87, + 0x21, 0xb4, 0xdf, 0xc6, 0x3d, 0x87, 0xd6, 0xd4, 0x6f, 0x70, 0x69, 0x08, 0x4a, 0xc9, 0xca, 0x3f, + 0x01, 0x00, 0x00, 0xff, 0xff, 0x66, 0x4a, 0xf1, 0xe3, 0x7f, 0x0f, 0x00, 0x00, } func (this *QuerySecretContractRequest) Equal(that interface{}) bool { From 18d32bd97a9b24001b469c25f982f90734bf48fa Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 14 Jun 2023 13:11:37 +0300 Subject: [PATCH 035/164] Fix ambiguous err var segfaults after migrate Also: - Make it less ambiguous in init & exec - TestMigrateVmError --- x/compute/internal/keeper/keeper.go | 58 ++++++++++--------- .../keeper/secret_contracts_migrate_test.go | 15 +++++ x/compute/internal/keeper/test_common.go | 11 ++++ 3 files changed, 56 insertions(+), 28 deletions(-) diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index b371abdcf..d77acb19e 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -413,13 +413,13 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.A modeInfoBytes := []byte{} pkBytes := []byte{} signerSig := []byte{} - var err error + var initError error // If no callback signature - we should send the actual msg sender sign bytes and signature if callbackSig == nil { - signBytes, signMode, modeInfoBytes, pkBytes, signerSig, err = k.GetTxInfo(ctx, creator) - if err != nil { - return nil, nil, err + signBytes, signMode, modeInfoBytes, pkBytes, signerSig, initError = k.GetTxInfo(ctx, creator) + if initError != nil { + return nil, nil, initError } } @@ -483,21 +483,21 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.A // instantiate wasm contract gas := gasForContract(ctx) - response, key, adminProof, gasUsed, err := k.wasmer.Instantiate(codeInfo.CodeHash, env, initMsg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, verificationInfo, admin) + response, key, adminProof, gasUsed, initError := k.wasmer.Instantiate(codeInfo.CodeHash, env, initMsg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, verificationInfo, admin) consumeGas(ctx, gasUsed) - if err != nil { + if initError != nil { switch res := response.(type) { //nolint:gocritic case v1wasmTypes.DataWithInternalReplyInfo: - result, e := json.Marshal(res) - if e != nil { - return nil, nil, sdkerrors.Wrap(e, "couldn't marshal internal reply info") + result, jsonError := json.Marshal(res) + if jsonError != nil { + return nil, nil, sdkerrors.Wrap(jsonError, "couldn't marshal internal reply info") } - return contractAddress, result, sdkerrors.Wrap(types.ErrInstantiateFailed, err.Error()) + return contractAddress, result, sdkerrors.Wrap(types.ErrInstantiateFailed, initError.Error()) } - return contractAddress, nil, sdkerrors.Wrap(types.ErrInstantiateFailed, err.Error()) + return contractAddress, nil, sdkerrors.Wrap(types.ErrInstantiateFailed, initError.Error()) } switch res := response.(type) { @@ -640,11 +640,12 @@ func (k Keeper) Execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller if execErr != nil { var result sdk.Result + var jsonError error switch res := response.(type) { //nolint:gocritic case v1wasmTypes.DataWithInternalReplyInfo: - result.Data, err = json.Marshal(res) - if err != nil { - return nil, sdkerrors.Wrap(err, "couldn't marshal internal reply info") + result.Data, jsonError = json.Marshal(res) + if jsonError != nil { + return nil, sdkerrors.Wrap(jsonError, "couldn't marshal internal reply info") } } @@ -1286,9 +1287,23 @@ func (k Keeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller // instantiate wasm contract gas := gasForContract(ctx) - response, newContractKey, proof, gasUsed, err := k.wasmer.Migrate(newCodeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, gasMeter(ctx), gas, verificationInfo, adminAddr, adminProof) + response, newContractKey, proof, gasUsed, migrateErr := k.wasmer.Migrate(newCodeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, gasMeter(ctx), gas, verificationInfo, adminAddr, adminProof) consumeGas(ctx, gasUsed) + if migrateErr != nil { + var result []byte + var jsonError error + switch res := response.(type) { //nolint:gocritic + case v1wasmTypes.DataWithInternalReplyInfo: + result, jsonError = json.Marshal(res) + if jsonError != nil { + return nil, sdkerrors.Wrap(jsonError, "couldn't marshal internal reply info") + } + } + + return result, sdkerrors.Wrap(types.ErrExecuteFailed, migrateErr.Error()) + } + // update contract key with new one k.SetContractKey(ctx, contractAddress, &types.ContractKey{ Key: newContractKey, @@ -1298,19 +1313,6 @@ func (k Keeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller }, }) - if err != nil { - var result []byte - switch res := response.(type) { //nolint:gocritic - case v1wasmTypes.DataWithInternalReplyInfo: - result, err = json.Marshal(res) - if err != nil { - return nil, sdkerrors.Wrap(err, "couldn't marshal internal reply info") - } - } - - return result, sdkerrors.Wrap(types.ErrExecuteFailed, err.Error()) - } - // delete old secondary index entry k.removeFromContractCodeSecondaryIndex(ctx, contractAddress, k.getLastContractHistoryEntry(ctx, contractAddress)) // persist migration updates diff --git a/x/compute/internal/keeper/secret_contracts_migrate_test.go b/x/compute/internal/keeper/secret_contracts_migrate_test.go index 102a60629..752da7006 100644 --- a/x/compute/internal/keeper/secret_contracts_migrate_test.go +++ b/x/compute/internal/keeper/secret_contracts_migrate_test.go @@ -79,3 +79,18 @@ func TestMigrateContractFromDifferentAccount(t *testing.T) { _, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, WalletB, privKeyB, `{"migrate":{}}`, false, true, math.MaxUint64) require.NotNil(t, err) } + +func TestMigrateVmError(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[migrateContractV1], sdk.NewCoins()) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[migrateContractV2], walletA) + + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"Nop":{}}`, true, true, defaultGasForTests) + + _, _, data, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"test":{}}`, true, true, defaultGasForTests, 0) + require.Empty(t, execErr) + require.Empty(t, data) + + _, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"yolo":{}}`, true, true, math.MaxUint64) + require.Contains(t, err.Error(), "Error parsing into type migrate_contract_v2::msg::MigrateMsg: unknown variant `yolo`") +} diff --git a/x/compute/internal/keeper/test_common.go b/x/compute/internal/keeper/test_common.go index ed843d4af..edd4ea280 100644 --- a/x/compute/internal/keeper/test_common.go +++ b/x/compute/internal/keeper/test_common.go @@ -165,6 +165,17 @@ type ErrorResult struct { Generic error } +func (a ErrorResult) Error() string { + switch { + case a.CosmWasm != nil: + return a.CosmWasm.Error() + case a.Generic != nil: + return a.Generic.Error() + default: + panic("unknown error variant") + } +} + type MockIBCTransferKeeper struct { GetPortFn func(ctx sdk.Context) string } From 4c29eb46ea57577c14fd7a46d4a1c6135663e071 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 14 Jun 2023 14:02:11 +0300 Subject: [PATCH 036/164] Use migrate error code when mograte fails Instead of execute error code --- x/compute/internal/keeper/keeper.go | 4 ++-- x/compute/internal/keeper/msg_dispatcher.go | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index d77acb19e..1b81dedbb 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -1301,7 +1301,7 @@ func (k Keeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller } } - return result, sdkerrors.Wrap(types.ErrExecuteFailed, migrateErr.Error()) + return result, sdkerrors.Wrap(types.ErrMigrationFailed, migrateErr.Error()) } // update contract key with new one @@ -1348,7 +1348,7 @@ func (k Keeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller return data, nil default: - return nil, sdkerrors.Wrap(types.ErrExecuteFailed, fmt.Sprintf("cannot detect response type: %+v", res)) + return nil, sdkerrors.Wrap(types.ErrMigrationFailed, fmt.Sprintf("cannot detect response type: %+v", res)) } } diff --git a/x/compute/internal/keeper/msg_dispatcher.go b/x/compute/internal/keeper/msg_dispatcher.go index 718fd17bd..ad13aa813 100644 --- a/x/compute/internal/keeper/msg_dispatcher.go +++ b/x/compute/internal/keeper/msg_dispatcher.go @@ -160,6 +160,7 @@ func redactError(err error) (bool, error) { e := strings.ReplaceAll(err.Error(), "encrypted: ", "") e = strings.ReplaceAll(e, ": execute contract failed", "") e = strings.ReplaceAll(e, ": instantiate contract failed", "") + e = strings.ReplaceAll(e, ": migrate contract failed", "") return false, fmt.Errorf("%s", e) } From a1ae101dff301cd5c50777c3da093ab713c6654e Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 14 Jun 2023 14:08:34 +0300 Subject: [PATCH 037/164] lint --- x/registration/internal/types/reg_keys.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/registration/internal/types/reg_keys.go b/x/registration/internal/types/reg_keys.go index bd9e883bc..7eee9a04f 100644 --- a/x/registration/internal/types/reg_keys.go +++ b/x/registration/internal/types/reg_keys.go @@ -3,7 +3,7 @@ package types func GetApiKey() ([]byte, error) { - apiKeyFile, err := Asset("api_key.txt") + apiKeyFile, err := Asset("api_key.txt") //nolint:typecheck if err != nil { return nil, err } @@ -12,7 +12,7 @@ func GetApiKey() ([]byte, error) { } func GetSpid() ([]byte, error) { - apiKeyFile, err := Asset("spid.txt") + apiKeyFile, err := Asset("spid.txt") //nolint:typecheck if err != nil { return nil, err } From ee1bab9b4ee9510505cbe23244906c093ae7a36d Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 14 Jun 2023 14:23:46 +0300 Subject: [PATCH 038/164] TestMigrateStdError --- .vscode/settings.json | 2 ++ Makefile | 17 ++++++++++------ .../migration/contract-v1/Makefile | 4 ++-- .../migration/contract-v1/src/contract.rs | 2 +- .../migration/contract-v2/Makefile | 4 ++-- .../migration/contract-v2/src/contract.rs | 3 ++- .../migration/contract-v2/src/msg.rs | 1 + .../keeper/secret_contracts_migrate_test.go | 19 ++++++++++++------ .../keeper/testdata/migrate_contract_v1.wasm | Bin 141215 -> 141291 bytes .../keeper/testdata/migrate_contract_v2.wasm | Bin 145767 -> 147156 bytes 10 files changed, 34 insertions(+), 18 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 82e6f6b73..100ae5511 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,6 +10,8 @@ "cosmwasm/contracts/v1/compute-tests/ibc-test-contract/Cargo.toml", "cosmwasm/contracts/v1/compute-tests/bench-contract/Cargo.toml", "cosmwasm/contracts/v010/compute-tests/test-compute-contract/Cargo.toml", + "cosmwasm/contracts/v1/compute-tests/migration/contract-v1/Cargo.toml", + "cosmwasm/contracts/v1/compute-tests/migration/contract-v2/Cargo.toml", "integration-tests/contract-v1/Cargo.toml", "integration-tests/contract-v0.10/Cargo.toml", "go-cosmwasm/Cargo.toml", diff --git a/Makefile b/Makefile index 7e466e467..d1079c19d 100644 --- a/Makefile +++ b/Makefile @@ -416,7 +416,7 @@ build-bench-contract: $(MAKE) -C $(TEST_CONTRACT_V1_PATH)/bench-contract cp $(TEST_CONTRACT_V1_PATH)/bench-contract/*.wasm $(TEST_COMPUTE_MODULE_PATH)/ -build-test-contract: +build-test-contracts: # echo "" | sudo add-apt-repository ppa:hnakamur/binaryen # sudo apt update # sudo apt install -y binaryen @@ -426,14 +426,19 @@ build-test-contract: cp $(TEST_CONTRACT_V1_PATH)/test-compute-contract/*.wasm $(TEST_COMPUTE_MODULE_PATH)/ $(MAKE) -C $(TEST_CONTRACT_V1_PATH)/ibc-test-contract cp $(TEST_CONTRACT_V1_PATH)/ibc-test-contract/*.wasm $(TEST_COMPUTE_MODULE_PATH)/ + $(MAKE) -C $(TEST_CONTRACT_V1_PATH)/migration/contract-v1 + mv $(TEST_CONTRACT_V1_PATH)/migration/contract-v1/*.wasm $(TEST_COMPUTE_MODULE_PATH)/ + $(MAKE) -C $(TEST_CONTRACT_V1_PATH)/migration/contract-v2 + mv $(TEST_CONTRACT_V1_PATH)/migration/contract-v2/*.wasm $(TEST_COMPUTE_MODULE_PATH)/ -prep-go-tests: build-test-contract bin-data-sw + +prep-go-tests: build-test-contracts bin-data-sw # empty BUILD_PROFILE means debug mode which compiles faster SGX_MODE=SW $(MAKE) build-linux cp ./$(EXECUTE_ENCLAVE_PATH)/librust_cosmwasm_enclave.signed.so ./x/compute/internal/keeper cp ./$(EXECUTE_ENCLAVE_PATH)/librust_cosmwasm_enclave.signed.so . -go-tests: build-test-contract bin-data-sw +go-tests: build-test-contracts bin-data-sw SGX_MODE=SW $(MAKE) build-linux cp ./$(EXECUTE_ENCLAVE_PATH)/librust_cosmwasm_enclave.signed.so ./x/compute/internal/keeper cp ./$(EXECUTE_ENCLAVE_PATH)/librust_cosmwasm_enclave.signed.so . @@ -442,7 +447,7 @@ go-tests: build-test-contract bin-data-sw mkdir -p ./x/compute/internal/keeper/.sgx_secrets GOMAXPROCS=8 SGX_MODE=SW SCRT_SGX_STORAGE='./' go test -count 1 -failfast -timeout 90m -v ./x/compute/internal/... $(GO_TEST_ARGS) -go-tests-hw: build-test-contract bin-data +go-tests-hw: build-test-contracts bin-data # empty BUILD_PROFILE means debug mode which compiles faster SGX_MODE=HW $(MAKE) build-linux cp ./$(EXECUTE_ENCLAVE_PATH)/librust_cosmwasm_enclave.signed.so ./x/compute/internal/keeper @@ -457,7 +462,7 @@ go-tests-hw: build-test-contract bin-data enclave-tests: $(MAKE) -C cosmwasm/enclaves/test run -build-all-test-contracts: build-test-contract +build-all-test-contracts: build-test-contracts cd $(CW_CONTRACTS_V010_PATH)/gov && RUSTFLAGS='-C link-arg=-s' cargo build --release --target wasm32-unknown-unknown --locked wasm-opt -Os $(CW_CONTRACTS_V010_PATH)/gov/target/wasm32-unknown-unknown/release/gov.wasm -o $(TEST_CONTRACT_PATH)/gov.wasm @@ -483,7 +488,7 @@ build-all-test-contracts: build-test-contract wasm-opt -Os .$(CW_CONTRACTS_V010_PATH)/hackatom/target/wasm32-unknown-unknown/release/hackatom.wasm -o $(TEST_CONTRACT_PATH)/contract.wasm cat $(TEST_CONTRACT_PATH)/contract.wasm | gzip > $(TEST_CONTRACT_PATH)/contract.wasm.gzip -build-erc20-contract: build-test-contract +build-erc20-contract: build-test-contracts cd .$(CW_CONTRACTS_V010_PATH)/erc20 && RUSTFLAGS='-C link-arg=-s' cargo build --release --target wasm32-unknown-unknown --locked wasm-opt -Os .$(CW_CONTRACTS_V010_PATH)/erc20/target/wasm32-unknown-unknown/release/cw_erc20.wasm -o ./erc20.wasm diff --git a/cosmwasm/contracts/v1/compute-tests/migration/contract-v1/Makefile b/cosmwasm/contracts/v1/compute-tests/migration/contract-v1/Makefile index a876f0e68..06b14c6eb 100644 --- a/cosmwasm/contracts/v1/compute-tests/migration/contract-v1/Makefile +++ b/cosmwasm/contracts/v1/compute-tests/migration/contract-v1/Makefile @@ -1,4 +1,4 @@ -all: src/contract.rs src src src Cargo.toml Cargo.lock +all: src/contract.rs src Cargo.toml Cargo.lock rustup target add wasm32-unknown-unknown RUSTFLAGS='-C link-arg=-s' cargo build --release --target wasm32-unknown-unknown cp ./target/wasm32-unknown-unknown/release/migrate_contract_v1.wasm ./migrate_contract_v1.wasm @@ -6,4 +6,4 @@ all: src/contract.rs src src src Cargo.toml Cargo.lock clean: cargo clean - -rm -f ./v1-contract.wasm + -rm -f ./*.wasm diff --git a/cosmwasm/contracts/v1/compute-tests/migration/contract-v1/src/contract.rs b/cosmwasm/contracts/v1/compute-tests/migration/contract-v1/src/contract.rs index fe5760742..93ad43b20 100644 --- a/cosmwasm/contracts/v1/compute-tests/migration/contract-v1/src/contract.rs +++ b/cosmwasm/contracts/v1/compute-tests/migration/contract-v1/src/contract.rs @@ -14,7 +14,7 @@ pub fn instantiate( #[entry_point] pub fn execute( - deps: DepsMut, + _deps: DepsMut, _env: Env, _info: MessageInfo, msg: ExecuteMsg, diff --git a/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/Makefile b/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/Makefile index 79231f421..ef37f6be5 100644 --- a/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/Makefile +++ b/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/Makefile @@ -1,4 +1,4 @@ -all: src/contract.rs src src src Cargo.toml Cargo.lock +all: src/contract.rs src Cargo.toml Cargo.lock rustup target add wasm32-unknown-unknown RUSTFLAGS='-C link-arg=-s' cargo build --release --target wasm32-unknown-unknown cp ./target/wasm32-unknown-unknown/release/migrate_contract_v2.wasm ./migrate_contract_v2.wasm @@ -6,4 +6,4 @@ all: src/contract.rs src src src Cargo.toml Cargo.lock clean: cargo clean - -rm -f ./v1-contract.wasm + -rm -f ./*.wasm diff --git a/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/src/contract.rs b/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/src/contract.rs index c493b26cd..1d8875066 100644 --- a/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/src/contract.rs +++ b/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/src/contract.rs @@ -1,5 +1,5 @@ use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg}; -use cosmwasm_std::{entry_point, DepsMut, Env, MessageInfo, Response, StdResult}; +use cosmwasm_std::{entry_point, DepsMut, Env, MessageInfo, Response, StdError, StdResult}; #[entry_point] pub fn instantiate( @@ -38,6 +38,7 @@ pub fn execute( pub fn migrate(_deps: DepsMut, _env: Env, msg: MigrateMsg) -> StdResult { match msg { MigrateMsg::Migrate {} => Ok(Response::default()), + MigrateMsg::StdError {} => Err(StdError::generic_err("this is an std error")), } } diff --git a/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/src/msg.rs b/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/src/msg.rs index e4faa4d78..40e3ed018 100644 --- a/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/src/msg.rs +++ b/cosmwasm/contracts/v1/compute-tests/migration/contract-v2/src/msg.rs @@ -17,4 +17,5 @@ pub enum ExecuteMsg { #[serde(rename_all = "snake_case")] pub enum MigrateMsg { Migrate {}, + StdError {}, } diff --git a/x/compute/internal/keeper/secret_contracts_migrate_test.go b/x/compute/internal/keeper/secret_contracts_migrate_test.go index 752da7006..a5e8bcf6a 100644 --- a/x/compute/internal/keeper/secret_contracts_migrate_test.go +++ b/x/compute/internal/keeper/secret_contracts_migrate_test.go @@ -72,10 +72,6 @@ func TestMigrateContractFromDifferentAccount(t *testing.T) { _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"Nop":{}}`, true, true, defaultGasForTests) - _, _, data, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"test":{}}`, true, true, defaultGasForTests, 0) - require.Empty(t, execErr) - require.Empty(t, data) - _, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, WalletB, privKeyB, `{"migrate":{}}`, false, true, math.MaxUint64) require.NotNil(t, err) } @@ -87,10 +83,21 @@ func TestMigrateVmError(t *testing.T) { _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"Nop":{}}`, true, true, defaultGasForTests) + _, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"yolo":{}}`, true, true, math.MaxUint64) + require.Contains(t, err.Error(), "Error parsing into type migrate_contract_v2::msg::MigrateMsg: unknown variant `yolo`") +} + +func TestMigrateStdError(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[migrateContractV1], sdk.NewCoins()) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[migrateContractV2], walletA) + + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"Nop":{}}`, true, true, defaultGasForTests) + _, _, data, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"test":{}}`, true, true, defaultGasForTests, 0) require.Empty(t, execErr) require.Empty(t, data) - _, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"yolo":{}}`, true, true, math.MaxUint64) - require.Contains(t, err.Error(), "Error parsing into type migrate_contract_v2::msg::MigrateMsg: unknown variant `yolo`") + _, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"std_error":{}}`, true, true, math.MaxUint64) + require.Equal(t, err.Error(), "encrypted: Generic error: this is an std error") } diff --git a/x/compute/internal/keeper/testdata/migrate_contract_v1.wasm b/x/compute/internal/keeper/testdata/migrate_contract_v1.wasm index a49c4ebd98238e63dda7a1080c266a557f3de554..f5e5013df200cab0fe06bd44d8bfe7cda698c8e2 100755 GIT binary patch delta 15208 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 delta 17967 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 z Date: Thu, 15 Jun 2023 11:29:59 +0300 Subject: [PATCH 039/164] Verify init admin field inside the enclave --- .../src/contract_operations.rs | 17 +++-- .../src/contract_validation.rs | 36 +++++---- .../src/input_validation/msg_validation.rs | 58 +++++++++------ .../enclaves/shared/cosmos-types/src/types.rs | 73 +++++++++++++------ .../internal/keeper/distribution_test.go | 2 +- 5 files changed, 121 insertions(+), 65 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 50872969b..a834da7f6 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -8,7 +8,7 @@ use cw_types_generic::{BaseAddr, BaseEnv}; use cw_types_v010::encoding::Binary; use cw_types_v010::types::CanonicalAddr; -use enclave_cosmos_types::types::{ContractCode, HandleType, SigInfo}; +use enclave_cosmos_types::types::{ContractCode, HandleType, SigInfo, VerifyParamsType}; use enclave_crypto::{sha_256, Ed25519PublicKey}; use enclave_ffi_types::{Ctx, EnclaveError}; use log::*; @@ -85,7 +85,7 @@ pub fn init( env: &[u8], // blockchain state msg: &[u8], // probably function call and args sig_info: &[u8], // info about signature verification - _admin: &[u8], // admin's canonical address or null if no admin + admin: &[u8], // admin's canonical address or null if no admin ) -> Result { trace!("Starting init"); @@ -118,6 +118,7 @@ pub fn init( let canonical_contract_address = to_canonical(contract_address)?; let canonical_sender_address = to_canonical(sender)?; + let canonical_admin_address = CanonicalAddr::from_vec(admin.to_vec()); let contract_key = generate_contract_key( &canonical_sender_address, @@ -143,7 +144,8 @@ pub fn init( msg, true, true, - HandleType::HANDLE_TYPE_EXECUTE, // same behavior as execute + VerifyParamsType::Init, + Some(&canonical_admin_address), )?; // let duration = start.elapsed(); // trace!("Time elapsed in verify_params: {:?}", duration); @@ -261,7 +263,7 @@ pub fn migrate( env: &[u8], msg: &[u8], sig_info: &[u8], - _admin: &[u8], + admin: &[u8], admin_proof: &[u8], ) -> Result { debug!("Starting migrate"); @@ -295,6 +297,7 @@ pub fn migrate( let canonical_contract_address = to_canonical(contract_address)?; let canonical_sender_address = to_canonical(sender)?; + let canonical_admin_address = CanonicalAddr::from_vec(admin.to_vec()); let contract_key = generate_contract_key( &canonical_sender_address, @@ -335,7 +338,8 @@ pub fn migrate( msg, true, true, - HandleType::HANDLE_TYPE_EXECUTE, // same behavior as execute + VerifyParamsType::Migrate, + Some(&canonical_admin_address), )?; // let duration = start.elapsed(); // trace!("Time elapsed in verify_params: {:?}", duration); @@ -499,7 +503,8 @@ pub fn handle( msg, should_verify_sig_info, should_verify_input, - parsed_handle_type, + VerifyParamsType::HandleType(parsed_handle_type), + None, )?; let mut validated_msg = decrypted_msg.clone(); diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index e76d58535..bad7e925f 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -9,6 +9,7 @@ use cw_types_v010::types::{CanonicalAddr, Coin, HumanAddr}; use enclave_cosmos_types::traits::CosmosAminoPubkey; use enclave_cosmos_types::types::{ ContractCode, CosmosPubKey, DirectSdkMsg, HandleType, SigInfo, SignDoc, StdSignDoc, + VerifyParamsType, }; use enclave_crypto::traits::VerifyingKey; use enclave_crypto::{sha_256, AESKey, Hmac, Kdf, HASH_SIZE, KEY_MANAGER}; @@ -366,7 +367,8 @@ pub fn verify_params( #[cfg(feature = "light-client-validation")] og_msg: &[u8], should_verify_sig_info: bool, should_verify_input: bool, - handle_type: HandleType, + verify_params_type: VerifyParamsType, + admin: Option<&CanonicalAddr>, ) -> Result<(), EnclaveError> { if should_verify_sig_info { debug!("Verifying message signatures for: {:?}", sig_info); @@ -380,7 +382,7 @@ pub fn verify_params( return Err(EnclaveError::ValidationFailure); } - verify_signature(sig_info, sender, handle_type)?; + verify_signature(sig_info, sender, verify_params_type)?; } if should_verify_input { @@ -390,7 +392,8 @@ pub fn verify_params( sender, contract_address, msg, - handle_type, + verify_params_type, + admin, )?; } @@ -402,9 +405,9 @@ pub fn verify_params( fn verify_signature( sig_info: &SigInfo, sender: &CanonicalAddr, - handle_type: HandleType, + verify_params_type: VerifyParamsType, ) -> Result<(), EnclaveError> { - let sender_public_key = get_signer(sig_info, sender, handle_type)?; + let sender_public_key = get_signer(sig_info, sender, verify_params_type)?; sender_public_key .verify_bytes( @@ -437,9 +440,10 @@ fn verify_input( sender: &CanonicalAddr, contract_address: &HumanAddr, msg: &SecretMessage, - handle_type: HandleType, + verify_params_types: VerifyParamsType, + admin: Option<&CanonicalAddr>, ) -> Result<(), EnclaveError> { - let messages = get_messages(sig_info, handle_type)?; + let messages = get_messages(sig_info, verify_params_types)?; let is_verified = verify_message_params( &messages, @@ -447,7 +451,8 @@ fn verify_input( sent_funds, contract_address, msg, - handle_type, + verify_params_types, + admin, ); if !is_verified { @@ -461,12 +466,13 @@ fn verify_input( fn get_signer( sign_info: &SigInfo, sender: &CanonicalAddr, - handle_type: HandleType, + verify_params_type: VerifyParamsType, ) -> Result { use cosmos_proto::tx::signing::SignMode::*; match sign_info.sign_mode { SIGN_MODE_DIRECT => { - let sign_doc = SignDoc::from_bytes(sign_info.sign_bytes.as_slice(), handle_type)?; + let sign_doc = + SignDoc::from_bytes(sign_info.sign_bytes.as_slice(), verify_params_type)?; trace!("sign doc: {:?}", sign_doc); // This verifies that signatures and sign bytes are self consistent @@ -525,12 +531,13 @@ fn get_signer( fn get_messages( sign_info: &SigInfo, - handle_type: HandleType, + verify_params_types: VerifyParamsType, ) -> Result, EnclaveError> { use cosmos_proto::tx::signing::SignMode::*; match sign_info.sign_mode { SIGN_MODE_DIRECT => { - let sign_doc = SignDoc::from_bytes(sign_info.sign_bytes.as_slice(), handle_type)?; + let sign_doc = + SignDoc::from_bytes(sign_info.sign_bytes.as_slice(), verify_params_types)?; trace!("sign doc: {:?}", sign_doc); Ok(sign_doc.body.messages) @@ -643,12 +650,13 @@ fn verify_message_params( sent_funds: &[Coin], contract_address: &HumanAddr, sent_msg: &SecretMessage, - handle_type: HandleType, + verify_params_types: VerifyParamsType, + admin: Option<&CanonicalAddr>, ) -> bool { info!("Verifying sdk message against wasm input..."); // If msg is not found (is None) then it means message verification failed, // since it didn't find a matching signed message - let sdk_msg = verify_and_get_sdk_msg(messages, sender, sent_msg, handle_type); + let sdk_msg = verify_and_get_sdk_msg(messages, sender, sent_msg, verify_params_types, admin); if sdk_msg.is_none() { debug!("Message verification failed!"); trace!( diff --git a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs index 2ac948596..478c78c0f 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs @@ -1,9 +1,12 @@ -use cw_types_v010::{encoding::Binary, types::CanonicalAddr}; +use cw_types_v010::{ + encoding::Binary, + types::{CanonicalAddr, HumanAddr}, +}; use cw_types_v1::ibc::IbcPacketReceiveMsg; use enclave_cosmos_types::types::{ is_transfer_ack_error, DirectSdkMsg, FungibleTokenPacketData, HandleType, IBCLifecycleComplete, IBCLifecycleCompleteOptions, IBCPacketAckMsg, IBCPacketTimeoutMsg, IbcHooksIncomingTransferMsg, - IncentivizedAcknowledgement, Packet, + IncentivizedAcknowledgement, Packet, VerifyParamsType, }; use log::*; @@ -13,28 +16,39 @@ use crate::types::SecretMessage; /// Get the cosmwasm message that contains the encrypted message pub fn verify_and_get_sdk_msg<'sd>( messages: &'sd [DirectSdkMsg], - msg_sender: &CanonicalAddr, + sent_sender: &CanonicalAddr, sent_msg: &SecretMessage, - handle_type: HandleType, + verify_params_types: VerifyParamsType, + sent_admin: Option<&CanonicalAddr>, ) -> Option<&'sd DirectSdkMsg> { - trace!("get_verified_msg: {:?}", messages); + trace!("verify_and_get_sdk_msg: {:?}", messages); messages.iter().find(|&m| match m { DirectSdkMsg::Other => false, - DirectSdkMsg::MsgExecuteContract { msg, sender, .. } - | DirectSdkMsg::MsgInstantiateContract { + DirectSdkMsg::MsgInstantiateContract { init_msg: msg, sender, + admin, .. + } => { + let empty_canon = &CanonicalAddr(Binary(vec![])); + let empty_human = HumanAddr("".to_string()); + let sent_admin = sent_admin.unwrap_or(empty_canon); + let sent_admin = &HumanAddr::from_canonical(sent_admin).unwrap_or(empty_human); + + sent_admin == admin && sent_sender == sender && &sent_msg.to_vec() == msg } + DirectSdkMsg::MsgExecuteContract { msg, sender, .. } | DirectSdkMsg::MsgMigrateContract { msg, sender, .. } => { - msg_sender == sender && &sent_msg.to_vec() == msg + sent_sender == sender && &sent_msg.to_vec() == msg } - DirectSdkMsg::MsgRecvPacket { packet, .. } => match handle_type { - HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE => verify_ibc_packet_recv(sent_msg, packet), - HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER => { - verify_ibc_wasm_hooks_incoming_transfer(sent_msg, packet) + DirectSdkMsg::MsgRecvPacket { packet, .. } => match verify_params_types { + VerifyParamsType::HandleType(HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE) => { + verify_ibc_packet_recv(sent_msg, packet) } + VerifyParamsType::HandleType( + HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER, + ) => verify_ibc_wasm_hooks_incoming_transfer(sent_msg, packet), _ => false, }, DirectSdkMsg::MsgAcknowledgement { @@ -42,22 +56,22 @@ pub fn verify_and_get_sdk_msg<'sd>( acknowledgement, signer, .. - } => match handle_type { - HandleType::HANDLE_TYPE_IBC_PACKET_ACK => { + } => match verify_params_types { + VerifyParamsType::HandleType(HandleType::HANDLE_TYPE_IBC_PACKET_ACK) => { verify_ibc_packet_ack(sent_msg, packet, acknowledgement, signer) } - HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_ACK => { - verify_ibc_wasm_hooks_outgoing_transfer_ack(sent_msg, packet, acknowledgement) - } + VerifyParamsType::HandleType( + HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_ACK, + ) => verify_ibc_wasm_hooks_outgoing_transfer_ack(sent_msg, packet, acknowledgement), _ => false, }, - DirectSdkMsg::MsgTimeout { packet, signer, .. } => match handle_type { - HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT => { + DirectSdkMsg::MsgTimeout { packet, signer, .. } => match verify_params_types { + VerifyParamsType::HandleType(HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT) => { verify_ibc_packet_timeout(sent_msg, packet, signer) } - HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_TIMEOUT => { - verify_ibc_wasm_hooks_outgoing_transfer_timeout(sent_msg, packet) - } + VerifyParamsType::HandleType( + HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_TIMEOUT, + ) => verify_ibc_wasm_hooks_outgoing_transfer_timeout(sent_msg, packet), _ => false, }, }) diff --git a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs index 2eea11dee..35abda35f 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs @@ -202,6 +202,16 @@ impl HandleType { } } +#[allow(non_camel_case_types)] +#[derive(Deserialize, Clone, Debug, PartialEq, Copy)] +pub enum VerifyParamsType { + HandleType(HandleType), + Init, + Migrate, + UpdateAdmin, + ClearAdmin, +} + // This is called `VerificationInfo` on the Go side #[derive(Deserialize, Clone, Debug, PartialEq)] pub struct SigInfo { @@ -233,7 +243,10 @@ pub struct SignDoc { } impl SignDoc { - pub fn from_bytes(bytes: &[u8], handle_type: HandleType) -> Result { + pub fn from_bytes( + bytes: &[u8], + verify_params_type: VerifyParamsType, + ) -> Result { let raw_sign_doc = proto::tx::tx::SignDoc::parse_from_bytes(bytes).map_err(|err| { warn!( "got an error while trying to deserialize sign doc bytes from protobuf: {}: {}", @@ -243,7 +256,7 @@ impl SignDoc { EnclaveError::FailedToDeserialize })?; - let body = TxBody::from_bytes(&raw_sign_doc.body_bytes, handle_type)?; + let body = TxBody::from_bytes(&raw_sign_doc.body_bytes, verify_params_type)?; let auth_info = AuthInfo::from_bytes(&raw_sign_doc.auth_info_bytes)?; Ok(Self { @@ -266,7 +279,10 @@ pub struct TxBody { } impl TxBody { - pub fn from_bytes(bytes: &[u8], handle_type: HandleType) -> Result { + pub fn from_bytes( + bytes: &[u8], + verify_params_type: VerifyParamsType, + ) -> Result { let tx_body = proto::tx::tx::TxBody::parse_from_bytes(bytes).map_err(|err| { warn!( "got an error while trying to deserialize cosmos message body bytes from protobuf: {}: {}", @@ -279,7 +295,7 @@ impl TxBody { let messages = tx_body .messages .into_iter() - .map(|any| DirectSdkMsg::from_bytes(&any.value, handle_type)) + .map(|any| DirectSdkMsg::from_bytes(&any.value, verify_params_type)) .collect::, _>>()?; Ok(TxBody { @@ -645,31 +661,44 @@ pub enum DirectSdkMsg { } impl DirectSdkMsg { - pub fn from_bytes(bytes: &[u8], handle_type: HandleType) -> Result { + pub fn from_bytes( + bytes: &[u8], + verify_params_type: VerifyParamsType, + ) -> Result { // Assaf: This function needs a refactor, as some protobufs are // compatible, e.g. try_parse_execute succeeds in parsing MsgRecvPacket as // MsgExecuteContract, so for now for each field of MsgExecuteContract we also need // to add a sanity check - match handle_type { - HandleType::HANDLE_TYPE_EXECUTE => Self::try_parse_execute(bytes) - .or_else(|_| Self::try_parse_instantiate(bytes)) - .or_else(|_| Self::try_parse_migrate(bytes)), - HandleType::HANDLE_TYPE_REPLY => Ok(DirectSdkMsg::Other), - HandleType::HANDLE_TYPE_IBC_CHANNEL_OPEN => Ok(DirectSdkMsg::Other), - HandleType::HANDLE_TYPE_IBC_CHANNEL_CONNECT => Ok(DirectSdkMsg::Other), - HandleType::HANDLE_TYPE_IBC_CHANNEL_CLOSE => Ok(DirectSdkMsg::Other), - HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE - | HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER => { - Self::try_parse_ibc_recv_packet(bytes) + match verify_params_type { + VerifyParamsType::Init => Self::try_parse_instantiate(bytes), + VerifyParamsType::HandleType(HandleType::HANDLE_TYPE_EXECUTE) => { + Self::try_parse_execute(bytes) + } + VerifyParamsType::Migrate => Self::try_parse_migrate(bytes), + VerifyParamsType::UpdateAdmin => Ok(DirectSdkMsg::Other), + VerifyParamsType::ClearAdmin => Ok(DirectSdkMsg::Other), + VerifyParamsType::HandleType(HandleType::HANDLE_TYPE_REPLY) => Ok(DirectSdkMsg::Other), + VerifyParamsType::HandleType(HandleType::HANDLE_TYPE_IBC_CHANNEL_OPEN) => { + Ok(DirectSdkMsg::Other) } - HandleType::HANDLE_TYPE_IBC_PACKET_ACK - | HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_ACK => { - Self::try_parse_ibc_ack(bytes) + VerifyParamsType::HandleType(HandleType::HANDLE_TYPE_IBC_CHANNEL_CONNECT) => { + Ok(DirectSdkMsg::Other) } - HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT - | HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_TIMEOUT => { - Self::try_parse_ibc_timeout(bytes) + VerifyParamsType::HandleType(HandleType::HANDLE_TYPE_IBC_CHANNEL_CLOSE) => { + Ok(DirectSdkMsg::Other) } + VerifyParamsType::HandleType(HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE) + | VerifyParamsType::HandleType( + HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER, + ) => Self::try_parse_ibc_recv_packet(bytes), + VerifyParamsType::HandleType(HandleType::HANDLE_TYPE_IBC_PACKET_ACK) + | VerifyParamsType::HandleType( + HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_ACK, + ) => Self::try_parse_ibc_ack(bytes), + VerifyParamsType::HandleType(HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT) + | VerifyParamsType::HandleType( + HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_TIMEOUT, + ) => Self::try_parse_ibc_timeout(bytes), } } diff --git a/x/compute/internal/keeper/distribution_test.go b/x/compute/internal/keeper/distribution_test.go index c532b9fb7..9c484a2aa 100644 --- a/x/compute/internal/keeper/distribution_test.go +++ b/x/compute/internal/keeper/distribution_test.go @@ -80,7 +80,7 @@ func TestDistributionRewards(t *testing.T) { require.NoError(t, err) ctx = PrepareInitSignedTx(t, keeper, ctx, creator, nil, creatorPrivKey, initBz, govId, nil) - govAddr, _, err := keeper.Instantiate(ctx, govId, creator, creator, initBz, "gidi gov", nil, nil) + govAddr, _, err := keeper.Instantiate(ctx, govId, creator, nil, initBz, "gidi gov", nil, nil) require.NoError(t, err) require.NotEmpty(t, govAddr) From cbf0818efd0613a341922723b738f579fd4e2384 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Thu, 15 Jun 2023 11:57:59 +0300 Subject: [PATCH 040/164] TestInputAdminMismatch --- .../keeper/secret_contracts_init_test.go | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/x/compute/internal/keeper/secret_contracts_init_test.go b/x/compute/internal/keeper/secret_contracts_init_test.go index 2e84810d5..d5257fadb 100644 --- a/x/compute/internal/keeper/secret_contracts_init_test.go +++ b/x/compute/internal/keeper/secret_contracts_init_test.go @@ -1051,3 +1051,65 @@ func TestInitCreateNewContract(t *testing.T) { }) } } + +func TestInputAdminMismatch(t *testing.T) { + for _, test := range []struct { + name string + inputNil bool + txNil bool + }{ + { + name: "tx is nil", + inputNil: true, + txNil: false, + }, + { + name: "input is nil", + inputNil: false, + txNil: true, + }, + { + name: "happy path 1", + inputNil: false, + txNil: false, + }, + { + name: "happy path 2", + inputNil: true, + txNil: true, + }, + } { + for _, testContract := range testContracts { + t.Run(test.name, func(t *testing.T) { + t.Run(testContract.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privWalletA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) + + initMsg := []byte(codeHash + `{"nop":{}}`) + enc, _ := wasmCtx.Encrypt(initMsg) + + inputAdmin := walletA + if test.inputNil { + inputAdmin = nil + } + txAdmin := walletA + if test.txNil { + txAdmin = nil + } + + ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, txAdmin, privWalletA, enc, codeID, nil) + _, _, err := keeper.Instantiate(ctx, codeID, walletA, inputAdmin, enc, "some label", nil, nil) + + if test.inputNil != test.txNil { + nonce := enc[0:32] + innerErr := extractInnerError(t, err, nonce, false, testContract.IsCosmWasmV1) + + require.Error(t, innerErr) + require.Contains(t, innerErr.Error(), "Execution error: Enclave: failed to verify transaction signature") + } else { + require.Empty(t, err) + } + }) + }) + } + } +} From c08d1bf1e09fc2bac38f6c517ec7679a2ea4d8e0 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Thu, 15 Jun 2023 15:20:08 +0300 Subject: [PATCH 041/164] Verify migrate admin inside the enclave --- .../contract-engine/src/input_validation/msg_validation.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs index 478c78c0f..85d2f1a69 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs @@ -40,7 +40,9 @@ pub fn verify_and_get_sdk_msg<'sd>( } DirectSdkMsg::MsgExecuteContract { msg, sender, .. } | DirectSdkMsg::MsgMigrateContract { msg, sender, .. } => { - sent_sender == sender && &sent_msg.to_vec() == msg + let empty_canon = &CanonicalAddr(Binary(vec![])); + let sent_admin = sent_admin.unwrap_or(empty_canon); + sent_sender == sender && sent_admin == sender && &sent_msg.to_vec() == msg } DirectSdkMsg::MsgRecvPacket { packet, .. } => match verify_params_types { VerifyParamsType::HandleType(HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE) => { From f608d41fb542cd5d62268f5f043bb98a97b4daae Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 20 Jun 2023 12:14:30 +0300 Subject: [PATCH 042/164] Fix admin_sig on init --- .../enclaves/shared/contract-engine/src/contract_operations.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index a834da7f6..95b3db5b9 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -127,7 +127,7 @@ pub fn init( &canonical_contract_address, )?; - let admin_sig = generate_admin_signature(&canonical_sender_address.0 .0, &contract_key); + let admin_sig = generate_admin_signature(&canonical_admin_address.0 .0, &contract_key); let parsed_sig_info: SigInfo = extract_sig_info(sig_info)?; From f4da1314c11bd73bba9830d02c2f207f2dec17d3 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 20 Jun 2023 12:15:06 +0300 Subject: [PATCH 043/164] Refactor some of the enclave validation code --- .../src/contract_operations.rs | 10 +++--- .../contract_address_validation.rs | 31 ++++++------------- .../src/input_validation/msg_validation.rs | 8 +++-- .../src/input_validation/sender_validation.rs | 8 ++--- 4 files changed, 25 insertions(+), 32 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 95b3db5b9..573c29e35 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -55,7 +55,7 @@ we need to allocate memory regions inside the VM's instance and copy `env` & `msg` into those memory regions inside the VM's instance. */ -fn generate_admin_signature(admin: &[u8], contract_key: &[u8]) -> [u8; enclave_crypto::HASH_SIZE] { +fn generate_admin_proof(admin: &[u8], contract_key: &[u8]) -> [u8; enclave_crypto::HASH_SIZE] { let mut data_to_hash = vec![]; data_to_hash.extend_from_slice(admin); data_to_hash.extend_from_slice(contract_key); @@ -127,7 +127,7 @@ pub fn init( &canonical_contract_address, )?; - let admin_sig = generate_admin_signature(&canonical_admin_address.0 .0, &contract_key); + let admin_proof = generate_admin_proof(&canonical_admin_address.0 .0, &contract_key); let parsed_sig_info: SigInfo = extract_sig_info(sig_info)?; @@ -223,7 +223,7 @@ pub fn init( Ok(InitSuccess { output, contract_key, - admin_proof: admin_sig, + admin_proof, }) } @@ -308,9 +308,9 @@ pub fn migrate( let og_contract_key = base_env.get_contract_key()?; - let admin_sig = generate_admin_signature(&canonical_sender_address.0 .0, &og_contract_key); + let sneder_admin_proof = generate_admin_proof(&canonical_sender_address.0 .0, &og_contract_key); - if admin_sig != admin_proof { + if sneder_admin_proof != admin_proof { error!("Failed to validate admin signature for migrate"); return Err(EnclaveError::ValidationFailure); } diff --git a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/contract_address_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/contract_address_validation.rs index 13f22fbd4..1afa5e033 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/contract_address_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/contract_address_validation.rs @@ -9,13 +9,12 @@ use log::*; pub fn verify_contract_address(msg: &DirectSdkMsg, contract_address: &HumanAddr) -> bool { // Contract address is relevant only to execute, since during sending an instantiate message the contract address is not yet known match msg { - DirectSdkMsg::MsgExecuteContract { contract, .. } => { - verify_msg_execute_contract_address(contract_address, contract) - } - DirectSdkMsg::MsgMigrateContract { contract, .. } => { - verify_msg_migrate_contract_address(contract_address, contract) + DirectSdkMsg::MsgExecuteContract { contract, .. } + | DirectSdkMsg::MsgMigrateContract { contract, .. } => { + verify_msg_execute_or_migrate_contract_address(contract_address, contract) } // During sending an instantiate message the contract address is not yet known + // so we cannot extract it from the message and compare it to the one in env DirectSdkMsg::MsgInstantiateContract { .. } => true, DirectSdkMsg::MsgRecvPacket { packet: @@ -42,25 +41,15 @@ pub fn verify_contract_address(msg: &DirectSdkMsg, contract_address: &HumanAddr) } } -fn verify_msg_execute_contract_address(contract_address: &HumanAddr, contract: &HumanAddr) -> bool { - info!("Verifying contract address..."); - let is_verified = contract_address == contract; - if !is_verified { - trace!( - "Contract address sent to enclave {:?} is not the same as the signed one {:?}", - contract_address, - *contract - ); - } - is_verified -} - -fn verify_msg_migrate_contract_address(contract_address: &HumanAddr, contract: &HumanAddr) -> bool { - info!("Verifying contract address..."); +fn verify_msg_execute_or_migrate_contract_address( + contract_address: &HumanAddr, + contract: &HumanAddr, +) -> bool { + info!("verifying contract address..."); let is_verified = contract_address == contract; if !is_verified { trace!( - "Contract address sent to enclave {:?} is not the same as the signed one {:?}", + "contract address sent to enclave {:?} is not the same as the signed one {:?}", contract_address, *contract ); diff --git a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs index 85d2f1a69..357e1a7d8 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs @@ -33,15 +33,19 @@ pub fn verify_and_get_sdk_msg<'sd>( } => { let empty_canon = &CanonicalAddr(Binary(vec![])); let empty_human = HumanAddr("".to_string()); + let sent_admin = sent_admin.unwrap_or(empty_canon); let sent_admin = &HumanAddr::from_canonical(sent_admin).unwrap_or(empty_human); sent_admin == admin && sent_sender == sender && &sent_msg.to_vec() == msg } - DirectSdkMsg::MsgExecuteContract { msg, sender, .. } - | DirectSdkMsg::MsgMigrateContract { msg, sender, .. } => { + DirectSdkMsg::MsgExecuteContract { msg, sender, .. } => { + sent_sender == sender && &sent_msg.to_vec() == msg + } + DirectSdkMsg::MsgMigrateContract { msg, sender, .. } => { let empty_canon = &CanonicalAddr(Binary(vec![])); let sent_admin = sent_admin.unwrap_or(empty_canon); + sent_sender == sender && sent_admin == sender && &sent_msg.to_vec() == msg } DirectSdkMsg::MsgRecvPacket { packet, .. } => match verify_params_types { diff --git a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/sender_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/sender_validation.rs index d0511d9bf..8d2f981ab 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/sender_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/sender_validation.rs @@ -2,7 +2,7 @@ use cw_types_v010::types::CanonicalAddr; use enclave_cosmos_types::types::DirectSdkMsg; use log::*; -pub fn verify_sender(sdk_msg: &DirectSdkMsg, sender: &CanonicalAddr) -> Option { +pub fn verify_sender(sdk_msg: &DirectSdkMsg, sent_sender: &CanonicalAddr) -> Option { match sdk_msg { DirectSdkMsg::MsgRecvPacket { .. } | DirectSdkMsg::MsgAcknowledgement { .. } @@ -14,10 +14,10 @@ pub fn verify_sender(sdk_msg: &DirectSdkMsg, sender: &CanonicalAddr) -> Option { - if sdk_msg.sender() != Some(sender) { + if sdk_msg.sender() != Some(sent_sender) { trace!( - "sender {:?} did not match sdk message sender: {:?}", - sender, + "sent_sender {:?} did not match sdk message sender: {:?}", + sent_sender, sdk_msg ); return Some(false); From 0b7555a7b3996e131294199252157e0ec50baa91 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 20 Jun 2023 14:58:13 +0300 Subject: [PATCH 044/164] Add admin_proof_secret & contract_key_proof_secret Otherwise, both can be forged when sent into the enclave. This is done using the same method as when we prove a callback_sig. --- cosmwasm/enclaves/ffi-types/src/types.rs | 2 +- .../src/contract_operations.rs | 40 ++++++++++------- .../contract-engine/src/external/results.rs | 6 +-- cosmwasm/enclaves/shared/crypto/src/consts.rs | 2 + .../enclaves/shared/crypto/src/key_manager.rs | 44 +++++++++++++++++++ cosmwasm/packages/sgx-vm/src/wasmi/results.rs | 8 ++-- 6 files changed, 79 insertions(+), 23 deletions(-) diff --git a/cosmwasm/enclaves/ffi-types/src/types.rs b/cosmwasm/enclaves/ffi-types/src/types.rs index 33e653bd0..11afbacc4 100644 --- a/cosmwasm/enclaves/ffi-types/src/types.rs +++ b/cosmwasm/enclaves/ffi-types/src/types.rs @@ -330,7 +330,7 @@ pub enum MigrateResult { /// A pointer to the output of the calculation output: UserSpaceBuffer, new_contract_key: [u8; 64], - proof: [u8; 32], + contract_key_proof: [u8; 32], }, Failure { /// The error that happened in the enclave diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 573c29e35..405c6505b 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -9,7 +9,7 @@ use cw_types_v010::encoding::Binary; use cw_types_v010::types::CanonicalAddr; use enclave_cosmos_types::types::{ContractCode, HandleType, SigInfo, VerifyParamsType}; -use enclave_crypto::{sha_256, Ed25519PublicKey}; +use enclave_crypto::{sha_256, Ed25519PublicKey, KEY_MANAGER}; use enclave_ffi_types::{Ctx, EnclaveError}; use log::*; @@ -59,20 +59,30 @@ fn generate_admin_proof(admin: &[u8], contract_key: &[u8]) -> [u8; enclave_crypt let mut data_to_hash = vec![]; data_to_hash.extend_from_slice(admin); data_to_hash.extend_from_slice(contract_key); + + let admin_proof_secret = KEY_MANAGER.get_admin_proof_secret().unwrap(); + + data_to_hash.extend_from_slice(admin_proof_secret.get()); + sha_256(&data_to_hash) } fn generate_contract_key_proof( - address: &[u8], + contract_address: &[u8], code_hash: &[u8], prev_contract_key: &[u8], new_contract_key: &[u8], ) -> [u8; enclave_crypto::HASH_SIZE] { let mut data_to_hash = vec![]; - data_to_hash.extend_from_slice(address); + data_to_hash.extend_from_slice(contract_address); data_to_hash.extend_from_slice(code_hash); data_to_hash.extend_from_slice(prev_contract_key); data_to_hash.extend_from_slice(new_contract_key); + + let contract_key_proof_secret = KEY_MANAGER.get_contract_key_proof_secret().unwrap(); + + data_to_hash.extend_from_slice(contract_key_proof_secret.get()); + sha_256(&data_to_hash) } @@ -127,8 +137,6 @@ pub fn init( &canonical_contract_address, )?; - let admin_proof = generate_admin_proof(&canonical_admin_address.0 .0, &contract_key); - let parsed_sig_info: SigInfo = extract_sig_info(sig_info)?; let secret_msg = SecretMessage::from_slice(msg)?; @@ -220,6 +228,8 @@ pub fn init( // todo: can move the key to somewhere in the output message if we want + let admin_proof = generate_admin_proof(&canonical_admin_address.0 .0, &contract_key); + Ok(InitSuccess { output, contract_key, @@ -311,17 +321,10 @@ pub fn migrate( let sneder_admin_proof = generate_admin_proof(&canonical_sender_address.0 .0, &og_contract_key); if sneder_admin_proof != admin_proof { - error!("Failed to validate admin signature for migrate"); + error!("Failed to validate sender as current admin for migrate"); return Err(EnclaveError::ValidationFailure); } - debug!("validated migration proof successfully"); - - let contract_key_proof = generate_contract_key_proof( - &canonical_sender_address.0 .0, - &contract_code.hash(), - &og_contract_key, - &contract_key, - ); + debug!("Validated migration proof successfully"); let parsed_sig_info: SigInfo = extract_sig_info(sig_info)?; @@ -406,6 +409,13 @@ pub fn migrate( // todo: can move the key to somewhere in the output message if we want + let contract_key_proof = generate_contract_key_proof( + &canonical_sender_address.0 .0, + &contract_code.hash(), + &og_contract_key, + &contract_key, + ); + debug!( "Migrate success: {:?}, {:?}", contract_key, contract_key_proof @@ -414,7 +424,7 @@ pub fn migrate( Ok(MigrateSuccess { output, new_contract_key: contract_key, - proof: contract_key_proof, + contract_key_proof, }) } diff --git a/cosmwasm/enclaves/shared/contract-engine/src/external/results.rs b/cosmwasm/enclaves/shared/contract-engine/src/external/results.rs index bce0e5b4f..172ff51ab 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/external/results.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/external/results.rs @@ -85,7 +85,7 @@ pub struct MigrateSuccess { /// The output of the calculation pub output: Vec, pub new_contract_key: [u8; 64], - pub proof: [u8; 32], + pub contract_key_proof: [u8; 32], } pub fn result_migrate_success_to_result( @@ -95,7 +95,7 @@ pub fn result_migrate_success_to_result( Ok(MigrateSuccess { output, new_contract_key, - proof, + contract_key_proof, }) => { let user_buffer = unsafe { let mut user_buffer = std::mem::MaybeUninit::::uninit(); @@ -114,7 +114,7 @@ pub fn result_migrate_success_to_result( MigrateResult::Success { output: user_buffer, new_contract_key, - proof, + contract_key_proof, } } Err(err) => MigrateResult::Failure { err }, diff --git a/cosmwasm/enclaves/shared/crypto/src/consts.rs b/cosmwasm/enclaves/shared/crypto/src/consts.rs index 4804d4879..034c19efb 100644 --- a/cosmwasm/enclaves/shared/crypto/src/consts.rs +++ b/cosmwasm/enclaves/shared/crypto/src/consts.rs @@ -112,6 +112,8 @@ pub const CONSENSUS_STATE_IKM_DERIVE_ORDER: u32 = 3; pub const CONSENSUS_CALLBACK_SECRET_DERIVE_ORDER: u32 = 4; pub const RANDOMNESS_ENCRYPTION_KEY_SECRET_DERIVE_ORDER: u32 = 5; pub const INITIAL_RANDOMNESS_SEED_SECRET_DERIVE_ORDER: u32 = 6; +pub const ADMIN_PROOF_SECRET_DERIVE_ORDER: u32 = 7; +pub const CONTRACT_KEY_PROOF_SECRET_DERIVE_ORDER: u32 = 8; pub const ENCRYPTED_KEY_MAGIC_BYTES: &[u8; 6] = b"secret"; pub const CONSENSUS_SEED_VERSION: u16 = 2; diff --git a/cosmwasm/enclaves/shared/crypto/src/key_manager.rs b/cosmwasm/enclaves/shared/crypto/src/key_manager.rs index 47e31b429..309e2ab09 100644 --- a/cosmwasm/enclaves/shared/crypto/src/key_manager.rs +++ b/cosmwasm/enclaves/shared/crypto/src/key_manager.rs @@ -38,6 +38,8 @@ pub struct Keychain { #[cfg(feature = "random")] pub initial_randomness_seed: Option, registration_key: Option, + admin_proof_secret: Option, + contract_key_proof_secret: Option, } #[derive(Clone, Copy, Default)] @@ -89,6 +91,8 @@ impl Keychain { initial_randomness_seed: None, #[cfg(feature = "random")] random_encryption_key: None, + admin_proof_secret: None, + contract_key_proof_secret: None, }; let _ = x.generate_consensus_master_keys(); @@ -196,6 +200,20 @@ impl Keychain { }) } + pub fn get_admin_proof_secret(&self) -> Result { + self.admin_proof_secret.ok_or_else(|| { + error!("Error accessing admin_proof_secret (does not exist, or was not initialized)"); + CryptoError::ParsingError + }) + } + + pub fn get_contract_key_proof_secret(&self) -> Result { + self.contract_key_proof_secret.ok_or_else(|| { + error!("Error accessing contract_key_proof_secret (does not exist, or was not initialized)"); + CryptoError::ParsingError + }) + } + pub fn reseal_registration_key(&mut self) -> Result<(), EnclaveError> { match Self::unseal_registration_key() { Some(kp) => { @@ -435,6 +453,32 @@ impl Keychain { self.write_randomness_keys(); } + let admin_proof_secret = self + .consensus_seed + .unwrap() + .current + .derive_key_from_this(&ADMIN_PROOF_SECRET_DERIVE_ORDER.to_be_bytes()); + + self.admin_proof_secret = Some(admin_proof_secret); + + trace!( + "initial_randomness_seed: {:?}", + hex::encode(admin_proof_secret.get()) + ); + + let contract_key_proof_secret = self + .consensus_seed + .unwrap() + .current + .derive_key_from_this(&CONTRACT_KEY_PROOF_SECRET_DERIVE_ORDER.to_be_bytes()); + + self.contract_key_proof_secret = Some(contract_key_proof_secret); + + trace!( + "initial_randomness_seed: {:?}", + hex::encode(contract_key_proof_secret.get()) + ); + Ok(()) } diff --git a/cosmwasm/packages/sgx-vm/src/wasmi/results.rs b/cosmwasm/packages/sgx-vm/src/wasmi/results.rs index a6eadc5a9..063ce918e 100644 --- a/cosmwasm/packages/sgx-vm/src/wasmi/results.rs +++ b/cosmwasm/packages/sgx-vm/src/wasmi/results.rs @@ -40,11 +40,11 @@ pub fn migrate_result_to_vm_result(other: MigrateResult) -> VmResult Ok(MigrateSuccess { output: unsafe { exports::recover_buffer(output) }.unwrap_or_else(Vec::new), new_contract_key, - proof, + contract_key_proof, }), MigrateResult::Failure { err } => Err(err.into()), } @@ -55,13 +55,13 @@ pub struct MigrateSuccess { /// A pointer to the output of the execution output: Vec, new_contract_key: [u8; 64], - proof: [u8; 32], + contract_key_proof: [u8; 32], } impl MigrateSuccess { pub fn into_output(self) -> Vec { let mut out_vec = self.new_contract_key.to_vec(); - out_vec.extend_from_slice(&self.proof); + out_vec.extend_from_slice(&self.contract_key_proof); out_vec.extend_from_slice(&self.output); out_vec } From f0b92f413617f5a20ef0a5d939ab213b3f2b3785 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Mon, 26 Jun 2023 14:54:40 +0300 Subject: [PATCH 045/164] Implement update admin inside the enclave - Fix contract key proof generation in migrate - Fix contract key usage in handle start_engine() - Rename some vars/funcs for readability - Fix admin proof check on migrate - Fix contract key proof check on handle - refactor verify_params() to have less input params --- cosmwasm/enclaves/execute/Enclave.edl | 11 ++ cosmwasm/enclaves/ffi-types/cbindgen.toml | 1 + cosmwasm/enclaves/ffi-types/src/lib.rs | 2 +- cosmwasm/enclaves/ffi-types/src/types.rs | 11 ++ .../block-verifier/src/wasm_messages.rs | 3 + .../src/contract_operations.rs | 156 +++++++++++++----- .../src/contract_validation.rs | 71 ++++---- .../contract-engine/src/external/ecalls.rs | 60 ++++++- .../contract-engine/src/external/results.rs | 18 +- .../contract_address_validation.rs | 4 +- .../src/input_validation/msg_validation.rs | 67 ++++++-- .../send_funds_validations.rs | 4 +- .../src/input_validation/sender_validation.rs | 2 + .../shared/contract-engine/src/wasm3/mod.rs | 12 +- .../enclaves/shared/cosmos-types/src/types.rs | 100 ++++++++++- .../shared/cosmwasm-types/generic/src/lib.rs | 39 +++-- .../shared/cosmwasm-types/v0.10/src/types.rs | 23 +-- cosmwasm/packages/sgx-vm/src/calls.rs | 18 +- cosmwasm/packages/sgx-vm/src/instance.rs | 11 ++ cosmwasm/packages/sgx-vm/src/lib.rs | 4 +- cosmwasm/packages/sgx-vm/src/wasmi/imports.rs | 17 +- cosmwasm/packages/sgx-vm/src/wasmi/results.rs | 22 ++- cosmwasm/packages/sgx-vm/src/wasmi/wrapper.rs | 59 ++++++- go-cosmwasm/api/bindings.h | 12 ++ go-cosmwasm/api/lib.go | 49 ++++++ go-cosmwasm/api/lib_mock.go | 16 ++ go-cosmwasm/lib.go | 32 ++++ go-cosmwasm/src/lib.rs | 70 +++++++- x/compute/internal/keeper/keeper.go | 53 +++++- 29 files changed, 809 insertions(+), 138 deletions(-) diff --git a/cosmwasm/enclaves/execute/Enclave.edl b/cosmwasm/enclaves/execute/Enclave.edl index bd11407ed..d290faa79 100644 --- a/cosmwasm/enclaves/execute/Enclave.edl +++ b/cosmwasm/enclaves/execute/Enclave.edl @@ -124,6 +124,17 @@ enclave { uintptr_t admin_proof_len ); + public UpdateAdminResult ecall_update_admin( + [in, count=env_len] const uint8_t* env, + uintptr_t env_len, + [in, count=sig_info_len] const uint8_t* sig_info, + uintptr_t sig_info_len, + [in, count=admin_len] const uint8_t* admin, + uintptr_t admin_len, + [in, count=admin_proof_len] const uint8_t* admin_proof, + uintptr_t admin_proof_len + ); + public HealthCheckResult ecall_health_check(); public uint32_t ecall_run_tests(); diff --git a/cosmwasm/enclaves/ffi-types/cbindgen.toml b/cosmwasm/enclaves/ffi-types/cbindgen.toml index 88ad73974..7c40bacc3 100644 --- a/cosmwasm/enclaves/ffi-types/cbindgen.toml +++ b/cosmwasm/enclaves/ffi-types/cbindgen.toml @@ -37,6 +37,7 @@ include = [ "InitResult", "HandleResult", "MigrateResult", + "UpdateAdminResult", "QueryResult", "OcallReturn", "HealthCheckResult", diff --git a/cosmwasm/enclaves/ffi-types/src/lib.rs b/cosmwasm/enclaves/ffi-types/src/lib.rs index 4990ef72a..6e004ad6b 100644 --- a/cosmwasm/enclaves/ffi-types/src/lib.rs +++ b/cosmwasm/enclaves/ffi-types/src/lib.rs @@ -6,7 +6,7 @@ mod types; pub use types::{ Ctx, EnclaveBuffer, EnclaveError, HandleResult, HealthCheckResult, InitResult, MigrateResult, NodeAuthResult, OcallReturn, QueryResult, RuntimeConfiguration, UntrustedVmError, - UserSpaceBuffer, + UpdateAdminResult, UserSpaceBuffer, }; // On input, the encrypted seed is expected to contain 3 values: diff --git a/cosmwasm/enclaves/ffi-types/src/types.rs b/cosmwasm/enclaves/ffi-types/src/types.rs index 11afbacc4..affde69c4 100644 --- a/cosmwasm/enclaves/ffi-types/src/types.rs +++ b/cosmwasm/enclaves/ffi-types/src/types.rs @@ -338,6 +338,17 @@ pub enum MigrateResult { }, } +#[repr(C)] +pub enum UpdateAdminResult { + Success { + admin_proof: [u8; 32], + }, + Failure { + /// The error that happened in the enclave + err: EnclaveError, + }, +} + /// This struct is returned from ecall_query. /// cbindgen:prefix-with-name #[repr(C)] diff --git a/cosmwasm/enclaves/shared/block-verifier/src/wasm_messages.rs b/cosmwasm/enclaves/shared/block-verifier/src/wasm_messages.rs index f43b2eaa2..83207dca0 100644 --- a/cosmwasm/enclaves/shared/block-verifier/src/wasm_messages.rs +++ b/cosmwasm/enclaves/shared/block-verifier/src/wasm_messages.rs @@ -9,6 +9,9 @@ pub fn message_is_wasm(msg: &protobuf::well_known_types::Any) -> bool { msg.type_url.as_str(), "/secret.compute.v1beta1.MsgExecuteContract" | "/secret.compute.v1beta1.MsgInstantiateContract" + | "/secret.compute.v1beta1.MsgMigrateContract" + | "/secret.compute.v1beta1.MsgUpdateAdmin" + | "/secret.compute.v1beta1.MsgClearAdmin" ) } diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 405c6505b..f11fc1b06 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -19,7 +19,9 @@ use crate::cosmwasm_config::ContractOperation; use crate::contract_validation::verify_block_info; use crate::contract_validation::{ReplyParams, ValidatedMessage}; -use crate::external::results::{HandleSuccess, InitSuccess, MigrateSuccess, QuerySuccess}; +use crate::external::results::{ + HandleSuccess, InitSuccess, MigrateSuccess, QuerySuccess, UpdateAdminSuccess, +}; use crate::message::{is_ibc_msg, parse_message}; use crate::types::ParsedMessage; @@ -130,7 +132,10 @@ pub fn init( let canonical_sender_address = to_canonical(sender)?; let canonical_admin_address = CanonicalAddr::from_vec(admin.to_vec()); - let contract_key = generate_contract_key( + // contract_key is a unique key for each contract + // it's used in state encryption to prevent the same + // encryption keys from being used for different contracts + let og_contract_key = generate_contract_key( &canonical_sender_address, &block_height, &contract_hash, @@ -148,8 +153,6 @@ pub fn init( &canonical_sender_address, contract_address, &secret_msg, - #[cfg(feature = "light-client-validation")] - msg, true, true, VerifyParamsType::Init, @@ -176,7 +179,7 @@ pub fn init( context, gas_limit, &contract_code, - &contract_key, + &og_contract_key, ContractOperation::Init, query_depth, secret_msg.nonce, @@ -191,7 +194,12 @@ pub fn init( versioned_env.set_contract_hash(&contract_hash); #[cfg(feature = "random")] - set_random_in_env(block_height, &contract_key, &mut engine, &mut versioned_env); + set_random_in_env( + block_height, + &og_contract_key, + &mut engine, + &mut versioned_env, + ); update_msg_counter(block_height); //let start = Instant::now(); @@ -228,11 +236,11 @@ pub fn init( // todo: can move the key to somewhere in the output message if we want - let admin_proof = generate_admin_proof(&canonical_admin_address.0 .0, &contract_key); + let admin_proof = generate_admin_proof(&canonical_admin_address.0 .0, &og_contract_key); Ok(InitSuccess { output, - contract_key, + contract_key: og_contract_key, admin_proof, }) } @@ -309,18 +317,11 @@ pub fn migrate( let canonical_sender_address = to_canonical(sender)?; let canonical_admin_address = CanonicalAddr::from_vec(admin.to_vec()); - let contract_key = generate_contract_key( - &canonical_sender_address, - &block_height, - &contract_hash, - &canonical_contract_address, - )?; + let og_contract_key = base_env.get_original_contract_key()?; - let og_contract_key = base_env.get_contract_key()?; + let sender_admin_proof = generate_admin_proof(&canonical_sender_address.0 .0, &og_contract_key); - let sneder_admin_proof = generate_admin_proof(&canonical_sender_address.0 .0, &og_contract_key); - - if sneder_admin_proof != admin_proof { + if admin_proof != sender_admin_proof { error!("Failed to validate sender as current admin for migrate"); return Err(EnclaveError::ValidationFailure); } @@ -337,8 +338,6 @@ pub fn migrate( &canonical_sender_address, contract_address, &secret_msg, - #[cfg(feature = "light-client-validation")] - msg, true, true, VerifyParamsType::Migrate, @@ -365,7 +364,7 @@ pub fn migrate( context, gas_limit, &contract_code, - &contract_key, + &og_contract_key, ContractOperation::Migrate, query_depth, secret_msg.nonce, @@ -379,8 +378,20 @@ pub fn migrate( versioned_env.set_contract_hash(&contract_hash); + let new_contract_key = generate_contract_key( + &canonical_sender_address, + &block_height, + &contract_hash, + &canonical_contract_address, + )?; + #[cfg(feature = "random")] - set_random_in_env(block_height, &contract_key, &mut engine, &mut versioned_env); + set_random_in_env( + block_height, + &new_contract_key, + &mut engine, + &mut versioned_env, + ); update_msg_counter(block_height); let result = engine.migrate(&versioned_env, validated_msg); @@ -410,24 +421,81 @@ pub fn migrate( // todo: can move the key to somewhere in the output message if we want let contract_key_proof = generate_contract_key_proof( - &canonical_sender_address.0 .0, + &canonical_contract_address.0 .0, &contract_code.hash(), &og_contract_key, - &contract_key, + &new_contract_key, ); debug!( "Migrate success: {:?}, {:?}", - contract_key, contract_key_proof + new_contract_key, contract_key_proof ); Ok(MigrateSuccess { output, - new_contract_key: contract_key, + new_contract_key, contract_key_proof, }) } +pub fn update_admin( + env: &[u8], + sig_info: &[u8], + admin: &[u8], + admin_proof: &[u8], +) -> Result { + debug!("Starting update_admin"); + + let base_env: BaseEnv = extract_base_env(env)?; + + #[cfg(feature = "light-client-validation")] + { + verify_block_info(&base_env)?; + } + + let (sender, contract_address, _block_height, sent_funds) = base_env.get_verification_params(); + + let canonical_sender_address = to_canonical(sender)?; + let canonical_admin_address = CanonicalAddr::from_vec(admin.to_vec()); + + let og_contract_key = base_env.get_original_contract_key()?; + + let sender_admin_proof = generate_admin_proof(&canonical_sender_address.0 .0, &og_contract_key); + + if sender_admin_proof != admin_proof { + error!("Failed to validate sender as current admin for update_admin"); + return Err(EnclaveError::ValidationFailure); + } + debug!("Validated update_admin proof successfully"); + + let parsed_sig_info: SigInfo = extract_sig_info(sig_info)?; + + verify_params( + &parsed_sig_info, + sent_funds, + &canonical_sender_address, + contract_address, + &SecretMessage { + nonce: [0; 32], + user_public_key: [0; 32], + msg: vec![], + }, + true, + true, + VerifyParamsType::UpdateAdmin, + Some(&canonical_admin_address), + )?; + + let new_admin_proof = generate_admin_proof(&canonical_admin_address.0 .0, &og_contract_key); + + debug!("update_admin success: {:?}", new_admin_proof); + + Ok(UpdateAdminSuccess { + admin_proof: new_admin_proof, + }) +} + #[cfg_attr(feature = "cargo-clippy", allow(clippy::too_many_arguments))] pub fn handle( context: Ctx, @@ -462,16 +530,32 @@ pub fn handle( let canonical_contract_address = to_canonical(contract_address)?; - let mut contract_key = base_env.get_contract_key()?; - + // contract_key is unique for each contract + // it's used in state encryption to prevent the same + // encryption keys from being used for different contracts + let mut contract_key = base_env.get_current_contract_key()?; validate_contract_key(&contract_key, &canonical_contract_address, &contract_code)?; if base_env.was_migrated() { - println!("Contract was migrated, setting keys to original one"); - let og_key = base_env.get_original_contract_key().unwrap(); // was_migrated checks that this won't fail - contract_key = og_key.get_key(); + println!("Contract was migrated, validating proof"); + + // was_migrated checks that these won't fail + let og_contract_key = base_env.get_original_contract_key()?; + let sent_contract_key_proof = base_env.get_contract_key_proof()?; + + let contract_key_proof = generate_contract_key_proof( + &canonical_contract_address.0 .0, + &contract_code.hash(), + &og_contract_key, + &contract_key, // this is already validated + ); + + if sent_contract_key_proof != contract_key_proof { + error!("Failed to validate contract key proof for a migrated contract"); + return Err(EnclaveError::ValidationFailure); + } - // validate proof + contract_key = og_contract_key; // used in engine for state encryption } let parsed_sig_info: SigInfo = extract_sig_info(sig_info)?; @@ -509,8 +593,6 @@ pub fn handle( &canonical_sender_address, contract_address, &secret_msg, - #[cfg(feature = "light-client-validation")] - msg, should_verify_sig_info, should_verify_input, VerifyParamsType::HandleType(parsed_handle_type), @@ -668,7 +750,7 @@ pub fn query( let canonical_contract_address = to_canonical(contract_address)?; - let contract_key = base_env.get_contract_key()?; + let contract_key = base_env.get_current_contract_key()?; validate_contract_key(&contract_key, &canonical_contract_address, &contract_code)?; @@ -719,7 +801,7 @@ fn start_engine( context: Ctx, gas_limit: u64, contract_code: &ContractCode, - contract_key: &ContractKey, + og_contract_key: &ContractKey, operation: ContractOperation, query_depth: u32, nonce: IoNonce, @@ -731,7 +813,7 @@ fn start_engine( gas_limit, WasmCosts::default(), contract_code, - *contract_key, + *og_contract_key, operation, nonce, user_public_key, diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index bad7e925f..449354b83 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -68,9 +68,9 @@ pub fn verify_block_info(base_env: &BaseEnv) -> Result<(), EnclaveError> { } #[cfg(feature = "light-client-validation")] -pub fn check_msg_matches_state(msg: &[u8]) -> bool { - let mut verified_msgs = VERIFIED_MESSAGES.lock().unwrap(); - let remaining_msgs = verified_msgs.remaining(); +pub fn check_msg_matches_state(msg: &SecretMessage) -> bool { + let mut verified_wasm_msgs = VERIFIED_MESSAGES.lock().unwrap(); + let remaining_msgs = verified_wasm_msgs.remaining(); if remaining_msgs == 0 { error!("Failed to validate message, error 0x3555"); @@ -80,9 +80,10 @@ pub fn check_msg_matches_state(msg: &[u8]) -> bool { // Msgs might fail in the sdk before they reach the enclave. In this case we need to run through // all the messages available before we can determine that there has been a failure // this isn't an attack vector since this can happen anyway by manipulating the state between executions - while verified_msgs.remaining() > 0 { - if let Some(expected_msg) = verified_msgs.get_next() { - if is_subslice(&expected_msg, msg) { + let raw_msg = msg.to_vec(); + while verified_wasm_msgs.remaining() > 0 { + if let Some(expected_msg) = verified_wasm_msgs.get_next() { + if is_subslice(&expected_msg, &raw_msg) { return true; } } @@ -92,11 +93,14 @@ pub fn check_msg_matches_state(msg: &[u8]) -> bool { // if this message fails to verify we have to fail the rest of the TX, so we won't get any // other messages - verified_msgs.clear(); + verified_wasm_msgs.clear(); false } +/// contract_key is a unique key for each contract +/// it's used in state encryption to prevent the same +/// encryption keys from being used for different contracts pub fn generate_contract_key( sender: &CanonicalAddr, block_height: &u64, @@ -115,7 +119,7 @@ pub fn generate_contract_key( // otherwise we'd have to migrate all the contract_keys every time we rotate the seed // which is doable but requires one more ecall & just unnecessary // actually using consensus_state_ikm might be entirely unnecessary here but it's too - // painful at this point to change the protocol to remove it + // painful at this point to change the validation protocol to remove it &consensus_state_ikm.genesis, &sender_id, contract_hash, @@ -364,7 +368,6 @@ pub fn verify_params( sender: &CanonicalAddr, contract_address: &HumanAddr, msg: &SecretMessage, - #[cfg(feature = "light-client-validation")] og_msg: &[u8], should_verify_sig_info: bool, should_verify_input: bool, verify_params_type: VerifyParamsType, @@ -378,7 +381,7 @@ pub fn verify_params( } #[cfg(feature = "light-client-validation")] - if !check_msg_matches_state(og_msg) { + if !check_msg_matches_state(msg) { return Err(EnclaveError::ValidationFailure); } @@ -443,10 +446,10 @@ fn verify_input( verify_params_types: VerifyParamsType, admin: Option<&CanonicalAddr>, ) -> Result<(), EnclaveError> { - let messages = get_messages(sig_info, verify_params_types)?; + let sdk_messages = get_sdk_messages(sig_info, verify_params_types)?; - let is_verified = verify_message_params( - &messages, + let is_verified = verify_input_params( + &sdk_messages, sender, sent_funds, contract_address, @@ -529,7 +532,7 @@ fn get_signer( } } -fn get_messages( +fn get_sdk_messages( sign_info: &SigInfo, verify_params_types: VerifyParamsType, ) -> Result, EnclaveError> { @@ -644,30 +647,40 @@ fn verify_callback_sig_impl( true } -fn verify_message_params( - messages: &[DirectSdkMsg], +fn verify_input_params( + sdk_messages: &[DirectSdkMsg], sender: &CanonicalAddr, sent_funds: &[Coin], contract_address: &HumanAddr, - sent_msg: &SecretMessage, + sent_wasm_input: &SecretMessage, verify_params_types: VerifyParamsType, admin: Option<&CanonicalAddr>, ) -> bool { info!("Verifying sdk message against wasm input..."); // If msg is not found (is None) then it means message verification failed, // since it didn't find a matching signed message - let sdk_msg = verify_and_get_sdk_msg(messages, sender, sent_msg, verify_params_types, admin); - if sdk_msg.is_none() { - debug!("Message verification failed!"); - trace!( - "Message sent to contract {:?} by {:?} does not match any signed messages {:?}", - sent_msg.to_vec(), - sender, - messages - ); - return false; - } - let sdk_msg = sdk_msg.unwrap(); + let sdk_msg = verify_and_get_sdk_msg( + sdk_messages, + sender, + contract_address, + sent_wasm_input, + verify_params_types, + admin, + ); + + let sdk_msg = match sdk_msg { + Some(sdk_msg) => sdk_msg, + None => { + debug!("Message verification failed!"); + trace!( + "Message sent to contract {:?} by {:?} does not match any signed messages {:?}", + sent_wasm_input.to_vec(), + sender, + sdk_messages + ); + return false; + } + }; info!("Verifying message sender..."); if let Some(value) = verify_sender(sdk_msg, sender) { diff --git a/cosmwasm/enclaves/shared/contract-engine/src/external/ecalls.rs b/cosmwasm/enclaves/shared/contract-engine/src/external/ecalls.rs index 68c133eb8..ea348f3b0 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/external/ecalls.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/external/ecalls.rs @@ -9,7 +9,7 @@ use sgx_types::sgx_status_t; use enclave_ffi_types::{ Ctx, EnclaveBuffer, EnclaveError, HandleResult, HealthCheckResult, InitResult, MigrateResult, - QueryResult, RuntimeConfiguration, + QueryResult, RuntimeConfiguration, UpdateAdminResult, }; use enclave_utils::{oom_handler, validate_const_ptr, validate_mut_ptr}; @@ -17,6 +17,7 @@ use enclave_utils::{oom_handler, validate_const_ptr, validate_mut_ptr}; use crate::external::results::{ result_handle_success_to_handleresult, result_init_success_to_initresult, result_migrate_success_to_result, result_query_success_to_queryresult, + result_update_admin_success_to_result, }; lazy_static! { @@ -477,7 +478,7 @@ pub unsafe extern "C" fn ecall_migrate( *used_gas = gas_limit / 2; if oom_handler::get_then_clear_oom_happened() { - error!("Call ecall_handle failed because the enclave ran out of memory!"); + error!("Call ecall_migrate failed because the enclave ran out of memory!"); MigrateResult::Failure { err: EnclaveError::OutOfMemory, } @@ -490,6 +491,61 @@ pub unsafe extern "C" fn ecall_migrate( } } +/// # Safety +/// Always use protection +#[no_mangle] +pub unsafe extern "C" fn ecall_update_admin( + env: *const u8, + env_len: usize, + sig_info: *const u8, + sig_info_len: usize, + admin: *const u8, + admin_len: usize, + admin_proof: *const u8, + admin_proof_len: usize, +) -> UpdateAdminResult { + if let Err(err) = oom_handler::register_oom_handler() { + error!("Could not register OOM handler!"); + return UpdateAdminResult::Failure { err }; + } + + let failed_call = + || result_update_admin_success_to_result(Err(EnclaveError::FailedFunctionCall)); + validate_const_ptr!(env, env_len as usize, failed_call()); + validate_const_ptr!(sig_info, sig_info_len as usize, failed_call()); + validate_const_ptr!(admin, admin_len as usize, failed_call()); + validate_const_ptr!(admin_proof, admin_proof_len as usize, failed_call()); + + let env = std::slice::from_raw_parts(env, env_len); + let sig_info = std::slice::from_raw_parts(sig_info, sig_info_len); + let admin = std::slice::from_raw_parts(admin, admin_len); + let admin_proof = std::slice::from_raw_parts(admin_proof, admin_proof_len); + + let result = panic::catch_unwind(|| { + let result = crate::contract_operations::update_admin(env, sig_info, admin, admin_proof); + result_update_admin_success_to_result(result) + }); + + if let Err(err) = oom_handler::restore_safety_buffer() { + error!("Could not restore OOM safety buffer!"); + return UpdateAdminResult::Failure { err }; + } + + if let Ok(res) = result { + res + } else if oom_handler::get_then_clear_oom_happened() { + error!("Call ecall_update_admin failed because the enclave ran out of memory!"); + UpdateAdminResult::Failure { + err: EnclaveError::OutOfMemory, + } + } else { + error!("Call ecall_update_admin panicked unexpectedly!"); + UpdateAdminResult::Failure { + err: EnclaveError::Panic, + } + } +} + /// # Safety /// Always use protection #[no_mangle] diff --git a/cosmwasm/enclaves/shared/contract-engine/src/external/results.rs b/cosmwasm/enclaves/shared/contract-engine/src/external/results.rs index 172ff51ab..024c7e3b9 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/external/results.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/external/results.rs @@ -2,7 +2,7 @@ use sgx_types::sgx_status_t; use enclave_ffi_types::{ EnclaveError, HandleResult, InitResult, MigrateResult, QueryResult, UntrustedVmError, - UserSpaceBuffer, + UpdateAdminResult, UserSpaceBuffer, }; use crate::external::ocalls::ocall_allocate; @@ -80,7 +80,7 @@ pub fn result_handle_success_to_handleresult( } } -/// This struct is returned from a handle method. +/// This struct is returned from a migrate method. pub struct MigrateSuccess { /// The output of the calculation pub output: Vec, @@ -121,6 +121,20 @@ pub fn result_migrate_success_to_result( } } +/// This struct is returned from a migrate method. +pub struct UpdateAdminSuccess { + pub admin_proof: [u8; 32], +} + +pub fn result_update_admin_success_to_result( + result: Result, +) -> UpdateAdminResult { + match result { + Ok(UpdateAdminSuccess { admin_proof }) => UpdateAdminResult::Success { admin_proof }, + Err(err) => UpdateAdminResult::Failure { err }, + } +} + /// This struct is returned from a query method. pub struct QuerySuccess { /// The output of the calculation diff --git a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/contract_address_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/contract_address_validation.rs index 1afa5e033..d1d69837f 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/contract_address_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/contract_address_validation.rs @@ -10,7 +10,9 @@ pub fn verify_contract_address(msg: &DirectSdkMsg, contract_address: &HumanAddr) // Contract address is relevant only to execute, since during sending an instantiate message the contract address is not yet known match msg { DirectSdkMsg::MsgExecuteContract { contract, .. } - | DirectSdkMsg::MsgMigrateContract { contract, .. } => { + | DirectSdkMsg::MsgMigrateContract { contract, .. } + | DirectSdkMsg::MsgUpdateAdmin { contract, .. } + | DirectSdkMsg::MsgClearAdmin { contract, .. } => { verify_msg_execute_or_migrate_contract_address(contract_address, contract) } // During sending an instantiate message the contract address is not yet known diff --git a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs index 357e1a7d8..dc25a13da 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs @@ -15,15 +15,16 @@ use crate::types::SecretMessage; /// Get the cosmwasm message that contains the encrypted message pub fn verify_and_get_sdk_msg<'sd>( - messages: &'sd [DirectSdkMsg], + sdk_messages: &'sd [DirectSdkMsg], sent_sender: &CanonicalAddr, - sent_msg: &SecretMessage, + sent_contract_address: &HumanAddr, + sent_wasm_input: &SecretMessage, verify_params_types: VerifyParamsType, sent_admin: Option<&CanonicalAddr>, ) -> Option<&'sd DirectSdkMsg> { - trace!("verify_and_get_sdk_msg: {:?}", messages); + trace!("verify_and_get_sdk_msg: {:?}", sdk_messages); - messages.iter().find(|&m| match m { + sdk_messages.iter().find(|&m| match m { DirectSdkMsg::Other => false, DirectSdkMsg::MsgInstantiateContract { init_msg: msg, @@ -37,24 +38,56 @@ pub fn verify_and_get_sdk_msg<'sd>( let sent_admin = sent_admin.unwrap_or(empty_canon); let sent_admin = &HumanAddr::from_canonical(sent_admin).unwrap_or(empty_human); - sent_admin == admin && sent_sender == sender && &sent_msg.to_vec() == msg + sent_admin == admin && sent_sender == sender && &sent_wasm_input.to_vec() == msg } - DirectSdkMsg::MsgExecuteContract { msg, sender, .. } => { - sent_sender == sender && &sent_msg.to_vec() == msg + DirectSdkMsg::MsgExecuteContract { + msg, + sender, + contract, + .. + } => { + sent_sender == sender + && sent_contract_address == contract + && &sent_wasm_input.to_vec() == msg } - DirectSdkMsg::MsgMigrateContract { msg, sender, .. } => { + DirectSdkMsg::MsgMigrateContract { + msg, + sender, + contract, + .. + } => { let empty_canon = &CanonicalAddr(Binary(vec![])); let sent_admin = sent_admin.unwrap_or(empty_canon); - sent_sender == sender && sent_admin == sender && &sent_msg.to_vec() == msg + sent_sender == sender + && sent_admin == sender + && sent_contract_address == contract + && &sent_wasm_input.to_vec() == msg + } + DirectSdkMsg::MsgUpdateAdmin { + sender, + new_admin, + contract, + } => { + let empty_canon = &CanonicalAddr(Binary(vec![])); + let empty_human = HumanAddr("".to_string()); + let sent_admin = &HumanAddr::from_canonical(sent_admin.unwrap_or(empty_canon)) + .unwrap_or(empty_human); + + sent_sender == sender && sent_admin == new_admin && sent_contract_address == contract + } + DirectSdkMsg::MsgClearAdmin { sender, contract } => { + sent_sender == sender + && sent_admin == Some(&CanonicalAddr(Binary(vec![]))) + && sent_contract_address == contract } DirectSdkMsg::MsgRecvPacket { packet, .. } => match verify_params_types { VerifyParamsType::HandleType(HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE) => { - verify_ibc_packet_recv(sent_msg, packet) + verify_ibc_packet_recv(sent_wasm_input, packet) } VerifyParamsType::HandleType( HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER, - ) => verify_ibc_wasm_hooks_incoming_transfer(sent_msg, packet), + ) => verify_ibc_wasm_hooks_incoming_transfer(sent_wasm_input, packet), _ => false, }, DirectSdkMsg::MsgAcknowledgement { @@ -64,20 +97,24 @@ pub fn verify_and_get_sdk_msg<'sd>( .. } => match verify_params_types { VerifyParamsType::HandleType(HandleType::HANDLE_TYPE_IBC_PACKET_ACK) => { - verify_ibc_packet_ack(sent_msg, packet, acknowledgement, signer) + verify_ibc_packet_ack(sent_wasm_input, packet, acknowledgement, signer) } VerifyParamsType::HandleType( HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_ACK, - ) => verify_ibc_wasm_hooks_outgoing_transfer_ack(sent_msg, packet, acknowledgement), + ) => verify_ibc_wasm_hooks_outgoing_transfer_ack( + sent_wasm_input, + packet, + acknowledgement, + ), _ => false, }, DirectSdkMsg::MsgTimeout { packet, signer, .. } => match verify_params_types { VerifyParamsType::HandleType(HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT) => { - verify_ibc_packet_timeout(sent_msg, packet, signer) + verify_ibc_packet_timeout(sent_wasm_input, packet, signer) } VerifyParamsType::HandleType( HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_TIMEOUT, - ) => verify_ibc_wasm_hooks_outgoing_transfer_timeout(sent_msg, packet), + ) => verify_ibc_wasm_hooks_outgoing_transfer_timeout(sent_wasm_input, packet), _ => false, }, }) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/send_funds_validations.rs b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/send_funds_validations.rs index faa0d6647..4d0041e4e 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/send_funds_validations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/send_funds_validations.rs @@ -42,7 +42,9 @@ pub fn verify_sent_funds(msg: &DirectSdkMsg, sent_funds_msg: &[Coin]) -> bool { } DirectSdkMsg::MsgAcknowledgement { .. } | DirectSdkMsg::MsgTimeout { .. } - | DirectSdkMsg::MsgMigrateContract { .. } => sent_funds_msg.is_empty(), + | DirectSdkMsg::MsgMigrateContract { .. } + | DirectSdkMsg::MsgUpdateAdmin { .. } + | DirectSdkMsg::MsgClearAdmin { .. } => sent_funds_msg.is_empty(), } } diff --git a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/sender_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/sender_validation.rs index 8d2f981ab..c64ead42e 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/sender_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/sender_validation.rs @@ -13,6 +13,8 @@ pub fn verify_sender(sdk_msg: &DirectSdkMsg, sent_sender: &CanonicalAddr) -> Opt DirectSdkMsg::MsgExecuteContract { .. } | DirectSdkMsg::MsgInstantiateContract { .. } | DirectSdkMsg::MsgMigrateContract { .. } + | DirectSdkMsg::MsgUpdateAdmin { .. } + | DirectSdkMsg::MsgClearAdmin { .. } | DirectSdkMsg::Other => { if sdk_msg.sender() != Some(sent_sender) { trace!( diff --git a/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs b/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs index 2483b97fe..142fa8052 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs @@ -95,7 +95,7 @@ pub struct Context { gas_costs: WasmCosts, query_depth: u32, operation: ContractOperation, - contract_key: ContractKey, + og_contract_key: ContractKey, user_nonce: IoNonce, user_public_key: Ed25519PublicKey, kv_cache: KvCache, @@ -214,7 +214,7 @@ impl Engine { gas_limit: u64, gas_costs: WasmCosts, contract_code: &ContractCode, - contract_key: ContractKey, + og_contract_key: ContractKey, operation: ContractOperation, user_nonce: IoNonce, user_public_key: Ed25519PublicKey, @@ -230,7 +230,7 @@ impl Engine { gas_used_externally: 0, gas_costs, operation, - contract_key, + og_contract_key, user_nonce, user_public_key, kv_cache, @@ -633,7 +633,7 @@ impl Engine { &k, &v, &self.context.context, - &self.context.contract_key, + &self.context.og_contract_key, &get_encryption_salt(self.context.timestamp), ) .unwrap(); @@ -907,7 +907,7 @@ fn host_read_db( let (value, used_gas) = read_from_encrypted_state( &state_key_name, &context.context, - &context.contract_key, + &context.og_contract_key, match context.operation { ContractOperation::Init => true, ContractOperation::Handle => true, @@ -956,7 +956,7 @@ fn host_remove_db( context.kv_cache.remove(&state_key_name); let used_gas = - remove_from_encrypted_state(&state_key_name, &context.context, &context.contract_key)?; + remove_from_encrypted_state(&state_key_name, &context.context, &context.og_contract_key)?; context.use_gas_externally(used_gas); Ok(()) diff --git a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs index 35abda35f..acd901d0e 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs @@ -208,8 +208,9 @@ pub enum VerifyParamsType { HandleType(HandleType), Init, Migrate, + /// UpdateAdmin is used both for updating the admin and clearing the admin + /// (by passing an empty admin address) UpdateAdmin, - ClearAdmin, } // This is called `VerificationInfo` on the Go side @@ -336,6 +337,15 @@ pub enum AminoSdkMsg { code_id: String, msg: String, }, + MsgUpdateAdmin { + sender: HumanAddr, + new_admin: HumanAddr, + contract: HumanAddr, + }, + MsgClearAdmin { + sender: HumanAddr, + contract: HumanAddr, + }, // The core IBC messages don't support Amino #[serde(other, deserialize_with = "deserialize_ignore_any")] Other, @@ -375,6 +385,7 @@ impl AminoSdkMsg { ); EnclaveError::FailedToDeserialize })?; + Ok(DirectSdkMsg::MsgMigrateContract { sender, msg, @@ -401,6 +412,7 @@ impl AminoSdkMsg { EnclaveError::FailedToDeserialize })?; let msg = msg.0; + Ok(DirectSdkMsg::MsgExecuteContract { sender, contract, @@ -437,6 +449,7 @@ impl AminoSdkMsg { ); EnclaveError::FailedToDeserialize })?; + Ok(DirectSdkMsg::MsgInstantiateContract { sender, code_id, @@ -447,6 +460,30 @@ impl AminoSdkMsg { admin, }) } + AminoSdkMsg::MsgUpdateAdmin { + sender, + new_admin, + contract, + } => { + let sender = CanonicalAddr::from_human(&sender).map_err(|err| { + warn!("failed to turn human addr to canonical addr when parsing DirectSdkMsg: {:?}", err); + EnclaveError::FailedToDeserialize + })?; + + Ok(DirectSdkMsg::MsgUpdateAdmin { + sender, + new_admin, + contract, + }) + } + AminoSdkMsg::MsgClearAdmin { sender, contract } => { + let sender = CanonicalAddr::from_human(&sender).map_err(|err| { + warn!("failed to turn human addr to canonical addr when parsing DirectSdkMsg: {:?}", err); + EnclaveError::FailedToDeserialize + })?; + + Ok(DirectSdkMsg::MsgClearAdmin { sender, contract }) + } Self::Other => Ok(DirectSdkMsg::Other), } } @@ -629,6 +666,15 @@ pub enum DirectSdkMsg { msg: Vec, code_id: u64, }, + MsgUpdateAdmin { + sender: CanonicalAddr, + new_admin: HumanAddr, + contract: HumanAddr, + }, + MsgClearAdmin { + sender: CanonicalAddr, + contract: HumanAddr, + }, // IBC: // MsgChannelOpenInit {}, // TODO // MsgChannelOpenTry {}, // TODO @@ -675,8 +721,7 @@ impl DirectSdkMsg { Self::try_parse_execute(bytes) } VerifyParamsType::Migrate => Self::try_parse_migrate(bytes), - VerifyParamsType::UpdateAdmin => Ok(DirectSdkMsg::Other), - VerifyParamsType::ClearAdmin => Ok(DirectSdkMsg::Other), + VerifyParamsType::UpdateAdmin => Self::try_parse_update_admin(bytes), VerifyParamsType::HandleType(HandleType::HANDLE_TYPE_REPLY) => Ok(DirectSdkMsg::Other), VerifyParamsType::HandleType(HandleType::HANDLE_TYPE_IBC_CHANNEL_OPEN) => { Ok(DirectSdkMsg::Other) @@ -832,6 +877,51 @@ impl DirectSdkMsg { }) } + fn try_parse_update_admin(bytes: &[u8]) -> Result { + use proto::cosmwasm::msg::{MsgClearAdmin, MsgUpdateAdmin}; + + // We first try to parse as MsgUpdateAdmin, if that fails we try to parse as MsgClearAdmin + // The order is important as MsgClearAdmin is a subset of MsgUpdateAdmin and can succeed parsing MsgUpdateAdmin bytes as MsgClearAdmin + + let raw_msg = MsgUpdateAdmin::parse_from_bytes(bytes); + + if let Ok(raw_msg) = raw_msg { + trace!( + "try_parse_update_admin sender: len={} val={:?}", + raw_msg.sender.len(), + raw_msg.sender + ); + + let sender = CanonicalAddr::from_human(&HumanAddr(raw_msg.sender)) + .map_err(|_| EnclaveError::FailedToDeserialize)?; + + let new_admin = HumanAddr(raw_msg.new_admin); + + Ok(DirectSdkMsg::MsgUpdateAdmin { + sender, + new_admin, + contract: HumanAddr(raw_msg.contract), + }) + } else { + let raw_update_msg = MsgClearAdmin::parse_from_bytes(bytes) + .map_err(|_| EnclaveError::FailedToDeserialize)?; + + trace!( + "try_parse_migrate sender: len={} val={:?}", + raw_update_msg.sender.len(), + raw_update_msg.sender + ); + + let sender = CanonicalAddr::from_human(&HumanAddr(raw_update_msg.sender)) + .map_err(|_| EnclaveError::FailedToDeserialize)?; + + Ok(DirectSdkMsg::MsgClearAdmin { + sender, + contract: HumanAddr(raw_update_msg.contract), + }) + } + } + fn try_parse_instantiate(bytes: &[u8]) -> Result { use proto::cosmwasm::msg::MsgInstantiateContract; @@ -926,7 +1016,9 @@ impl DirectSdkMsg { match self { DirectSdkMsg::MsgExecuteContract { sender, .. } | DirectSdkMsg::MsgInstantiateContract { sender, .. } - | DirectSdkMsg::MsgMigrateContract { sender, .. } => Some(sender), + | DirectSdkMsg::MsgMigrateContract { sender, .. } + | DirectSdkMsg::MsgUpdateAdmin { sender, .. } + | DirectSdkMsg::MsgClearAdmin { sender, .. } => Some(sender), DirectSdkMsg::MsgRecvPacket { .. } => None, DirectSdkMsg::MsgAcknowledgement { .. } => None, DirectSdkMsg::MsgTimeout { .. } => None, diff --git a/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs b/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs index c926677b3..250a99359 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs @@ -5,13 +5,14 @@ use serde::{Deserialize, Serialize}; use cw_types_v010::encoding::Binary; use cw_types_v010::types as v010types; -use cw_types_v010::types::{ContractKeyWithProof, Env as V010Env, HumanAddr}; +use cw_types_v010::types::{Env as V010Env, HumanAddr}; use cw_types_v1::types::Env as V1Env; use cw_types_v1::types::MessageInfo as V1MessageInfo; use cw_types_v1::types::{self as v1types, Addr}; use enclave_ffi_types::EnclaveError; pub const CONTRACT_KEY_LENGTH: usize = 64; +pub const CONTRACT_KEY_PROOF_LENGTH: usize = 32; /// CosmwasmApiVersion is used to decide how to handle contract inputs and outputs #[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq)] @@ -39,15 +40,9 @@ pub type BaseCanoncalAddr = v010types::CanonicalAddr; pub struct BaseEnv(pub V010Env); impl BaseEnv { - pub fn get_contract_key(&self) -> Result<[u8; CONTRACT_KEY_LENGTH], EnclaveError> { - let contract_key = if let Some(b64_key) = &self.0.contract_key { - base64::decode(&b64_key.key).map_err(|err| { - warn!( - "got an error while trying to decode contract key {:?}: {}", - b64_key, err - ); - EnclaveError::FailedContractAuthentication - })? + pub fn get_current_contract_key(&self) -> Result<[u8; CONTRACT_KEY_LENGTH], EnclaveError> { + let contract_key = if let Some(contract_key) = &self.0.contract_key { + &contract_key.key.0 } else { warn!("Contract execute with empty contract key"); return Err(EnclaveError::FailedContractAuthentication); @@ -59,7 +54,7 @@ impl BaseEnv { } let mut key_as_bytes = [0u8; CONTRACT_KEY_LENGTH]; - key_as_bytes.copy_from_slice(&contract_key); + key_as_bytes.copy_from_slice(contract_key); Ok(key_as_bytes) } @@ -72,11 +67,27 @@ impl BaseEnv { } } - pub fn get_original_contract_key(&self) -> Option { + pub fn get_original_contract_key(&self) -> Result<[u8; CONTRACT_KEY_LENGTH], EnclaveError> { + if let Some(key) = &self.0.contract_key { + if self.was_migrated() { + Ok(key.original.clone().unwrap().get_key()) + } else { + self.get_current_contract_key() + } + } else { + Err(EnclaveError::FailedContractAuthentication) + } + } + + pub fn get_contract_key_proof(&self) -> Result<[u8; CONTRACT_KEY_PROOF_LENGTH], EnclaveError> { if let Some(key) = &self.0.contract_key { - key.original.clone() + if self.was_migrated() { + Ok(key.original.clone().unwrap().get_proof()) + } else { + Err(EnclaveError::FailedContractAuthentication) + } } else { - None + Err(EnclaveError::FailedContractAuthentication) } } diff --git a/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/types.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/types.rs index 19566b3f4..bfe7bccc2 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/types.rs @@ -20,6 +20,9 @@ use super::encoding::Binary; use crate::consts::BECH32_PREFIX_ACC_ADDR; +pub const CONTRACT_KEY_LENGTH: usize = 64; +pub const CONTRACT_KEY_PROOF_LENGTH: usize = 32; + #[derive(Serialize, Deserialize, Clone, Default, Debug, PartialEq)] pub struct HumanAddr(pub String); @@ -102,29 +105,27 @@ impl fmt::Display for CanonicalAddr { #[derive(Serialize, Deserialize, Clone, Default, Debug, PartialEq)] pub struct ContractKey { - pub key: String, + pub key: Binary, pub original: Option, } #[derive(Serialize, Deserialize, Clone, Default, Debug, PartialEq)] pub struct ContractKeyWithProof { - pub key: String, - pub proof: String, + pub key: Binary, + pub proof: Binary, } impl ContractKeyWithProof { - pub fn get_key(&self) -> [u8; 64] { - let mut output = [0u8; 64]; - let decoded = base64::decode(&self.key).unwrap(); - output.copy_from_slice(&decoded); + pub fn get_key(&self) -> [u8; CONTRACT_KEY_LENGTH] { + let mut output = [0u8; CONTRACT_KEY_LENGTH]; + output.copy_from_slice(&self.key.0); output } - pub fn decode_proof(&self) -> [u8; 32] { - let mut output = [0u8; 32]; - let decoded = base64::decode(&self.proof).unwrap(); - output.copy_from_slice(&decoded); + pub fn get_proof(&self) -> [u8; CONTRACT_KEY_PROOF_LENGTH] { + let mut output = [0u8; CONTRACT_KEY_PROOF_LENGTH]; + output.copy_from_slice(&self.proof.0); output } diff --git a/cosmwasm/packages/sgx-vm/src/calls.rs b/cosmwasm/packages/sgx-vm/src/calls.rs index 60d0c69cb..6181b8d52 100644 --- a/cosmwasm/packages/sgx-vm/src/calls.rs +++ b/cosmwasm/packages/sgx-vm/src/calls.rs @@ -72,7 +72,7 @@ pub fn call_query( } */ -/// Calls Wasm export "init" and returns raw data from the contract. +/// Calls Wasm export "migrate" and returns raw data from the contract. /// The result is length limited to prevent abuse but otherwise unchecked. pub fn call_migrate_raw( instance: &mut Instance, @@ -89,6 +89,22 @@ pub fn call_migrate_raw( + instance: &mut Instance, + env: &[u8], + sig_info: &[u8], + admin: &[u8], + admin_proof: &[u8], +) -> VmResult> { + instance.set_storage_readonly(false); + /* + call_raw(instance, "init", &[env, msg], MAX_LENGTH_INIT) + */ + instance.call_update_admin(env, sig_info, admin, admin_proof) +} + /// Calls Wasm export "init" and returns raw data from the contract. /// The result is length limited to prevent abuse but otherwise unchecked. pub fn call_init_raw( diff --git a/cosmwasm/packages/sgx-vm/src/instance.rs b/cosmwasm/packages/sgx-vm/src/instance.rs index e05e82776..b70521e86 100644 --- a/cosmwasm/packages/sgx-vm/src/instance.rs +++ b/cosmwasm/packages/sgx-vm/src/instance.rs @@ -338,6 +338,17 @@ where Ok(result.into_output()) } + pub fn call_update_admin( + &mut self, + env: &[u8], + sig_info: &[u8], + admin: &[u8], + admin_proof: &[u8], + ) -> VmResult> { + let result = self.inner.update_admin(env, sig_info, admin, admin_proof)?; + Ok(result.into_output()) + } + pub fn call_init( &mut self, env: &[u8], diff --git a/cosmwasm/packages/sgx-vm/src/lib.rs b/cosmwasm/packages/sgx-vm/src/lib.rs index a43e0371f..2f6dd50d2 100644 --- a/cosmwasm/packages/sgx-vm/src/lib.rs +++ b/cosmwasm/packages/sgx-vm/src/lib.rs @@ -30,7 +30,9 @@ mod random; pub mod enclave_tests; pub use crate::cache::CosmCache; -pub use crate::calls::{call_handle_raw, call_init_raw, call_migrate_raw, call_query_raw}; +pub use crate::calls::{ + call_handle_raw, call_init_raw, call_migrate_raw, call_query_raw, call_update_admin_raw, +}; pub use crate::checksum::Checksum; pub use crate::errors::{ CommunicationError, CommunicationResult, RegionValidationError, RegionValidationResult, diff --git a/cosmwasm/packages/sgx-vm/src/wasmi/imports.rs b/cosmwasm/packages/sgx-vm/src/wasmi/imports.rs index a516b3854..5c8ccf002 100644 --- a/cosmwasm/packages/sgx-vm/src/wasmi/imports.rs +++ b/cosmwasm/packages/sgx-vm/src/wasmi/imports.rs @@ -4,7 +4,9 @@ use log::*; use sgx_types::{sgx_enclave_id_t, sgx_status_t, SgxResult}; -use enclave_ffi_types::{Ctx, EnclaveBuffer, HandleResult, InitResult, MigrateResult, QueryResult}; +use enclave_ffi_types::{ + Ctx, EnclaveBuffer, HandleResult, InitResult, MigrateResult, QueryResult, UpdateAdminResult, +}; use crate::enclave::ENCLAVE_DOORBELL; @@ -37,6 +39,19 @@ extern "C" { admin_proof_len: usize, ) -> sgx_status_t; + pub fn ecall_update_admin( + eid: sgx_enclave_id_t, + retval: *mut UpdateAdminResult, + env: *const u8, + env_len: usize, + sig_info: *const u8, + sig_info_len: usize, + admin: *const u8, + admin_len: usize, + admin_proof: *const u8, + admin_proof_len: usize, + ) -> sgx_status_t; + /// Trigger the init method in a wasm contract pub fn ecall_init( eid: sgx_enclave_id_t, diff --git a/cosmwasm/packages/sgx-vm/src/wasmi/results.rs b/cosmwasm/packages/sgx-vm/src/wasmi/results.rs index 063ce918e..99ee6f72d 100644 --- a/cosmwasm/packages/sgx-vm/src/wasmi/results.rs +++ b/cosmwasm/packages/sgx-vm/src/wasmi/results.rs @@ -1,6 +1,6 @@ use super::exports; use crate::VmResult; -use enclave_ffi_types::{HandleResult, InitResult, MigrateResult, QueryResult}; +use enclave_ffi_types::{HandleResult, InitResult, MigrateResult, QueryResult, UpdateAdminResult}; /// This struct is returned from module initialization. pub struct InitSuccess { @@ -50,7 +50,14 @@ pub fn migrate_result_to_vm_result(other: MigrateResult) -> VmResult VmResult { + match other { + UpdateAdminResult::Success { admin_proof } => Ok(UpdateAdminSuccess { admin_proof }), + UpdateAdminResult::Failure { err } => Err(err.into()), + } +} + +/// This struct is returned from a migrate method. pub struct MigrateSuccess { /// A pointer to the output of the execution output: Vec, @@ -67,6 +74,17 @@ impl MigrateSuccess { } } +/// This struct is returned from a migrate method. +pub struct UpdateAdminSuccess { + admin_proof: [u8; 32], +} + +impl UpdateAdminSuccess { + pub fn into_output(self) -> Vec { + self.admin_proof.to_vec() + } +} + /// This struct is returned from a handle method. pub struct HandleSuccess { /// A pointer to the output of the execution diff --git a/cosmwasm/packages/sgx-vm/src/wasmi/wrapper.rs b/cosmwasm/packages/sgx-vm/src/wasmi/wrapper.rs index 7e19f982d..89856ea5e 100644 --- a/cosmwasm/packages/sgx-vm/src/wasmi/wrapper.rs +++ b/cosmwasm/packages/sgx-vm/src/wasmi/wrapper.rs @@ -10,11 +10,15 @@ use crate::enclave::ENCLAVE_DOORBELL; use crate::errors::{EnclaveError, VmResult}; use crate::{Querier, Storage, VmError}; -use enclave_ffi_types::{Ctx, HandleResult, InitResult, MigrateResult, QueryResult}; +use enclave_ffi_types::{ + Ctx, HandleResult, InitResult, MigrateResult, QueryResult, UpdateAdminResult, +}; use sgx_types::sgx_status_t; -use crate::wasmi::results::{migrate_result_to_vm_result, MigrateSuccess}; +use crate::wasmi::results::{ + migrate_result_to_vm_result, update_admin_result_to_vm_result, MigrateSuccess, +}; use log::*; use serde::Deserialize; @@ -22,7 +26,7 @@ use super::exports::FullContext; use super::imports; use super::results::{ handle_result_to_vm_result, init_result_to_vm_result, query_result_to_vm_result, HandleSuccess, - InitSuccess, QuerySuccess, + InitSuccess, QuerySuccess, UpdateAdminSuccess, }; pub struct Module @@ -102,7 +106,7 @@ where admin_proof: &[u8], ) -> VmResult { trace!( - "init() called with env: {:?} msg: {:?} gas_left: {}", + "migrate() called with env: {:?} msg: {:?} gas_left: {}", String::from_utf8_lossy(env), String::from_utf8_lossy(msg), self.gas_left() @@ -156,6 +160,53 @@ where } } + pub fn update_admin( + &mut self, + env: &[u8], + sig_info: &[u8], + admin: &[u8], + admin_proof: &[u8], + ) -> VmResult { + trace!( + "update_admin() called with env: {:?}", + String::from_utf8_lossy(env), + ); + + let mut update_admin_result = MaybeUninit::::uninit(); + + // Bind the token to a local variable to ensure its + // destructor runs in the end of the function + let enclave_access_token = ENCLAVE_DOORBELL + .get_access(1) // This can never be recursive + .ok_or_else(Self::busy_enclave_err)?; + let enclave = enclave_access_token.map_err(EnclaveError::sdk_err)?; + + let status = unsafe { + imports::ecall_update_admin( + enclave.geteid(), + update_admin_result.as_mut_ptr(), + env.as_ptr(), + env.len(), + sig_info.as_ptr(), + sig_info.len(), + admin.as_ptr(), + admin.len(), + admin_proof.as_ptr(), + admin_proof.len(), + ) + }; + + trace!("update_admin() returned"); + + match status { + sgx_status_t::SGX_SUCCESS => { + let update_admin_result = unsafe { update_admin_result.assume_init() }; + update_admin_result_to_vm_result(update_admin_result) + } + failure_status => Err(EnclaveError::sdk_err(failure_status).into()), + } + } + pub fn init( &mut self, env: &[u8], diff --git a/go-cosmwasm/api/bindings.h b/go-cosmwasm/api/bindings.h index 69e984da1..20093a827 100644 --- a/go-cosmwasm/api/bindings.h +++ b/go-cosmwasm/api/bindings.h @@ -237,3 +237,15 @@ Buffer submit_block_signatures(Buffer header, Buffer txs, Buffer random, Buffer *err); + +Buffer update_admin(cache_t *cache, + Buffer contract_id, + Buffer params, + DB db, + GoApi api, + GoQuerier querier, + uint64_t gas_limit, + Buffer *err, + Buffer sig_info, + Buffer admin, + Buffer admin_proof); diff --git a/go-cosmwasm/api/lib.go b/go-cosmwasm/api/lib.go index 01409f0d7..73577ad8e 100644 --- a/go-cosmwasm/api/lib.go +++ b/go-cosmwasm/api/lib.go @@ -203,6 +203,55 @@ func Migrate( return receiveVector(res), uint64(gasUsed), nil } +func UpdateAdmin( + cache Cache, + code_id []byte, + params []byte, + gasMeter *GasMeter, + store KVStore, + api *GoAPI, + querier *Querier, + gasLimit uint64, + sigInfo []byte, + admin []byte, + adminProof []byte, +) ([]byte, error) { + id := sendSlice(code_id) + defer freeAfterSend(id) + p := sendSlice(params) + defer freeAfterSend(p) + + // set up a new stack frame to handle iterators + counter := startContract() + defer endContract(counter) + + dbState := buildDBState(store, counter) + db := buildDB(&dbState, gasMeter) + + s := sendSlice(sigInfo) + defer freeAfterSend(s) + a := buildAPI(api) + q := buildQuerier(querier) + errmsg := C.Buffer{} + + adminBuffer := sendSlice(admin) + defer freeAfterSend(adminBuffer) + + adminProofBuffer := sendSlice(adminProof) + defer freeAfterSend(adminProofBuffer) + + //// This is done in order to ensure that goroutines don't + //// swap threads between recursive calls to the enclave. + //runtime.LockOSThread() + //defer runtime.UnlockOSThread() + + res, err := C.update_admin(cache.ptr, id, p, db, a, q, u64(gasLimit), &errmsg, s, adminBuffer, adminProofBuffer) + if err != nil && err.(syscall.Errno) != C.ErrnoValue_Success { + return nil, errorWithMessage(err, errmsg) + } + return receiveVector(res), nil +} + func Instantiate( cache Cache, code_id []byte, diff --git a/go-cosmwasm/api/lib_mock.go b/go-cosmwasm/api/lib_mock.go index c94892f8d..59ebe0d98 100644 --- a/go-cosmwasm/api/lib_mock.go +++ b/go-cosmwasm/api/lib_mock.go @@ -112,6 +112,22 @@ func Migrate( return nil, 0, nil } +func UpdateAdmin( + cache Cache, + code_id []byte, + params []byte, + gasMeter *GasMeter, + store KVStore, + api *GoAPI, + querier *Querier, + gasLimit uint64, + sigInfo []byte, + admin []byte, + adminProof []byte, +) ([]byte, error) { + return nil, nil +} + func Instantiate( cache Cache, code_id []byte, diff --git a/go-cosmwasm/lib.go b/go-cosmwasm/lib.go index 35397e9c5..8b3082d12 100644 --- a/go-cosmwasm/lib.go +++ b/go-cosmwasm/lib.go @@ -493,3 +493,35 @@ func (w *Wasmer) Migrate( return nil, nil, nil, gasUsed, fmt.Errorf("instantiate: cannot detect response type (v0.10 or v1)") } + +// UpdateAdmin will update or clear a contract admin. +func (w *Wasmer) UpdateAdmin( + newCodeId CodeHash, + env types.Env, + store KVStore, + goapi GoAPI, + querier Querier, + gasMeter GasMeter, + gasLimit uint64, + sigInfo types.VerificationInfo, + admin []byte, + adminProof []byte, + // newAdminProof, error +) ([]byte, error) { + paramBin, err := json.Marshal(env) + if err != nil { + return nil, err + } + + sigInfoBin, err := json.Marshal(sigInfo) + if err != nil { + return nil, err + } + + newAdminProof, err := api.UpdateAdmin(w.cache, newCodeId, paramBin, &gasMeter, store, &goapi, &querier, gasLimit, sigInfoBin, admin, adminProof) + if err != nil { + return nil, err + } + + return newAdminProof, nil +} diff --git a/go-cosmwasm/src/lib.rs b/go-cosmwasm/src/lib.rs index 2bc9200c3..3f0bcb9e0 100644 --- a/go-cosmwasm/src/lib.rs +++ b/go-cosmwasm/src/lib.rs @@ -21,8 +21,8 @@ use crate::error::{clear_error, handle_c_error, handle_c_error_default, set_erro use cosmwasm_sgx_vm::untrusted_init_bootstrap; use cosmwasm_sgx_vm::{ - call_handle_raw, call_init_raw, call_migrate_raw, call_query_raw, features_from_csv, Checksum, - CosmCache, Extern, + call_handle_raw, call_init_raw, call_migrate_raw, call_query_raw, call_update_admin_raw, + features_from_csv, Checksum, CosmCache, Extern, }; use cosmwasm_sgx_vm::{ create_attestation_report_u, untrusted_get_encrypted_genesis_seed, @@ -576,6 +576,72 @@ fn do_migrate( Ok(res?) } +#[no_mangle] +pub extern "C" fn update_admin( + cache: *mut cache_t, + contract_id: Buffer, + params: Buffer, + db: DB, + api: GoApi, + querier: GoQuerier, + gas_limit: u64, + err: Option<&mut Buffer>, + sig_info: Buffer, + admin: Buffer, + admin_proof: Buffer, +) -> Buffer { + let r = match to_cache(cache) { + Some(c) => catch_unwind(AssertUnwindSafe(move || { + do_update_admin( + c, + contract_id, + params, + db, + api, + querier, + gas_limit, + sig_info, + admin, + admin_proof, + ) + })) + .unwrap_or_else(|_| Err(Error::panic())), + None => Err(Error::empty_arg(CACHE_ARG)), + }; + let data = handle_c_error(r, err); + Buffer::from_vec(data) +} + +#[allow(clippy::too_many_arguments)] +fn do_update_admin( + cache: &mut CosmCache, + code_id: Buffer, + params: Buffer, + db: DB, + api: GoApi, + querier: GoQuerier, + gas_limit: u64, + sig_info: Buffer, + admin: Buffer, + admin_proof: Buffer, +) -> Result, Error> { + let code_id: Checksum = unsafe { code_id.read() } + .ok_or_else(|| Error::empty_arg(CODE_ID_ARG))? + .try_into()?; + let params = unsafe { params.read() }.ok_or_else(|| Error::empty_arg(PARAMS_ARG))?; + let sig_info = unsafe { sig_info.read() }.ok_or_else(|| Error::empty_arg(SIG_INFO_ARG))?; + let admin = unsafe { admin.read() }.ok_or_else(|| Error::empty_arg(ADMIN_ARG))?; + let admin_proof = + unsafe { admin_proof.read() }.ok_or_else(|| Error::empty_arg(ADMIN_PROOF_ARG))?; + + let deps = to_extern(db, api, querier); + let mut instance = cache.get_instance(&code_id, deps, gas_limit)?; + // We only check this result after reporting gas usage and returning the instance into the cache. + let res = call_update_admin_raw(&mut instance, params, sig_info, admin, admin_proof); + instance.recycle(); + Ok(res?) +} + #[no_mangle] pub extern "C" fn handle( cache: *mut cache_t, diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index 1b81dedbb..c870dc8f7 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -1201,15 +1201,60 @@ func (k Keeper) reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply v1w } func (k Keeper) UpdateContractAdmin(ctx sdk.Context, contractAddress, caller, newAdmin sdk.AccAddress) error { - contractInfo := k.GetContractInfo(ctx, contractAddress) - if contractInfo == nil { - return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "unknown contract") + defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "update-contract-admin") + ctx.GasMeter().ConsumeGas(types.InstanceCost, "Loading CosmWasm module: update-contract-admin") + + contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddress) + if err != nil { + return err } if contractInfo.Admin != caller.String() { return sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "caller is not the admin") } + + signBytes, signMode, modeInfoBytes, pkBytes, signerSig, err := k.GetTxInfo(ctx, caller) + if err != nil { + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, err.Error()) + } + + verificationInfo := types.NewVerificationInfo(signBytes, signMode, modeInfoBytes, pkBytes, signerSig, nil) + + contractKey, err := k.GetContractKey(ctx, contractAddress) + if err != nil { + return err + } + + env := types.NewEnv(ctx, caller, sdk.Coins{}, contractAddress, &contractKey, nil) + + currentAdminProof := k.GetContractInfo(ctx, contractAddress).AdminProof + currentAdmin := k.GetContractInfo(ctx, contractAddress).Admin + + currentAdminAddress, err := sdk.AccAddressFromBech32(currentAdmin) + if err != nil { + return err + } + + // prepare querier + // TODO: this is unnecessary, get rid of this + querier := QueryHandler{ + Ctx: ctx, + Plugins: k.queryPlugins, + Caller: contractAddress, + } + + // instantiate wasm contract + gas := gasForContract(ctx) + + newAdminProof, updateAdminErr := k.wasmer.UpdateAdmin(codeInfo.CodeHash, env, prefixStore, cosmwasmAPI, querier, gasMeter(ctx), gas, verificationInfo, currentAdminAddress, currentAdminProof) + + if updateAdminErr != nil { + return updateAdminErr + } + contractInfo.Admin = newAdmin.String() - k.setContractInfo(ctx, contractAddress, contractInfo) + contractInfo.AdminProof = newAdminProof + k.setContractInfo(ctx, contractAddress, &contractInfo) + ctx.EventManager().EmitEvent(sdk.NewEvent( types.EventTypeUpdateContractAdmin, sdk.NewAttribute(types.AttributeKeyContractAddr, contractAddress.String()), From 3d79d505d8b6f168ba06fb25b502d97c4d5b6300 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 27 Jun 2023 11:04:00 +0300 Subject: [PATCH 046/164] Bypass weird C compiler error in ffi-types --- cosmwasm/enclaves/ffi-types/src/types.rs | 4 ++-- .../shared/contract-engine/src/external/ecalls.rs | 8 ++++---- .../shared/contract-engine/src/external/results.rs | 6 ++++-- cosmwasm/packages/sgx-vm/src/wasmi/results.rs | 6 ++++-- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/cosmwasm/enclaves/ffi-types/src/types.rs b/cosmwasm/enclaves/ffi-types/src/types.rs index affde69c4..b210b88c9 100644 --- a/cosmwasm/enclaves/ffi-types/src/types.rs +++ b/cosmwasm/enclaves/ffi-types/src/types.rs @@ -340,10 +340,10 @@ pub enum MigrateResult { #[repr(C)] pub enum UpdateAdminResult { - Success { + UpdateAdminSuccess { admin_proof: [u8; 32], }, - Failure { + UpdateAdminFailure { /// The error that happened in the enclave err: EnclaveError, }, diff --git a/cosmwasm/enclaves/shared/contract-engine/src/external/ecalls.rs b/cosmwasm/enclaves/shared/contract-engine/src/external/ecalls.rs index ea348f3b0..11bea78a8 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/external/ecalls.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/external/ecalls.rs @@ -506,7 +506,7 @@ pub unsafe extern "C" fn ecall_update_admin( ) -> UpdateAdminResult { if let Err(err) = oom_handler::register_oom_handler() { error!("Could not register OOM handler!"); - return UpdateAdminResult::Failure { err }; + return UpdateAdminResult::UpdateAdminFailure { err }; } let failed_call = @@ -528,19 +528,19 @@ pub unsafe extern "C" fn ecall_update_admin( if let Err(err) = oom_handler::restore_safety_buffer() { error!("Could not restore OOM safety buffer!"); - return UpdateAdminResult::Failure { err }; + return UpdateAdminResult::UpdateAdminFailure { err }; } if let Ok(res) = result { res } else if oom_handler::get_then_clear_oom_happened() { error!("Call ecall_update_admin failed because the enclave ran out of memory!"); - UpdateAdminResult::Failure { + UpdateAdminResult::UpdateAdminFailure { err: EnclaveError::OutOfMemory, } } else { error!("Call ecall_update_admin panicked unexpectedly!"); - UpdateAdminResult::Failure { + UpdateAdminResult::UpdateAdminFailure { err: EnclaveError::Panic, } } diff --git a/cosmwasm/enclaves/shared/contract-engine/src/external/results.rs b/cosmwasm/enclaves/shared/contract-engine/src/external/results.rs index 024c7e3b9..7b3328461 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/external/results.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/external/results.rs @@ -130,8 +130,10 @@ pub fn result_update_admin_success_to_result( result: Result, ) -> UpdateAdminResult { match result { - Ok(UpdateAdminSuccess { admin_proof }) => UpdateAdminResult::Success { admin_proof }, - Err(err) => UpdateAdminResult::Failure { err }, + Ok(UpdateAdminSuccess { admin_proof }) => { + UpdateAdminResult::UpdateAdminSuccess { admin_proof } + } + Err(err) => UpdateAdminResult::UpdateAdminFailure { err }, } } diff --git a/cosmwasm/packages/sgx-vm/src/wasmi/results.rs b/cosmwasm/packages/sgx-vm/src/wasmi/results.rs index 99ee6f72d..b8c444563 100644 --- a/cosmwasm/packages/sgx-vm/src/wasmi/results.rs +++ b/cosmwasm/packages/sgx-vm/src/wasmi/results.rs @@ -52,8 +52,10 @@ pub fn migrate_result_to_vm_result(other: MigrateResult) -> VmResult VmResult { match other { - UpdateAdminResult::Success { admin_proof } => Ok(UpdateAdminSuccess { admin_proof }), - UpdateAdminResult::Failure { err } => Err(err.into()), + UpdateAdminResult::UpdateAdminSuccess { admin_proof } => { + Ok(UpdateAdminSuccess { admin_proof }) + } + UpdateAdminResult::UpdateAdminFailure { err } => Err(err.into()), } } From 585b4299ce6521ad0834f707ccdf7a7946411a8b Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 27 Jun 2023 12:52:32 +0300 Subject: [PATCH 047/164] Refactor contract_key validation & fix it in query Query was not validating contract_key for migrated contracts, and didn't use the correct contract_key for state encryption --- .../src/contract_operations.rs | 66 ++++--------------- .../src/contract_validation.rs | 63 +++++++++++++++++- 2 files changed, 74 insertions(+), 55 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index f11fc1b06..a5fc4feea 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -18,7 +18,7 @@ use crate::cosmwasm_config::ContractOperation; #[cfg(feature = "light-client-validation")] use crate::contract_validation::verify_block_info; -use crate::contract_validation::{ReplyParams, ValidatedMessage}; +use crate::contract_validation::{generate_contract_key_proof, ReplyParams, ValidatedMessage}; use crate::external::results::{ HandleSuccess, InitSuccess, MigrateSuccess, QuerySuccess, UpdateAdminSuccess, }; @@ -69,25 +69,6 @@ fn generate_admin_proof(admin: &[u8], contract_key: &[u8]) -> [u8; enclave_crypt sha_256(&data_to_hash) } -fn generate_contract_key_proof( - contract_address: &[u8], - code_hash: &[u8], - prev_contract_key: &[u8], - new_contract_key: &[u8], -) -> [u8; enclave_crypto::HASH_SIZE] { - let mut data_to_hash = vec![]; - data_to_hash.extend_from_slice(contract_address); - data_to_hash.extend_from_slice(code_hash); - data_to_hash.extend_from_slice(prev_contract_key); - data_to_hash.extend_from_slice(new_contract_key); - - let contract_key_proof_secret = KEY_MANAGER.get_contract_key_proof_secret().unwrap(); - - data_to_hash.extend_from_slice(contract_key_proof_secret.get()); - - sha_256(&data_to_hash) -} - #[cfg_attr(feature = "cargo-clippy", allow(clippy::too_many_arguments))] pub fn init( context: Ctx, // need to pass this to read_db & write_db @@ -530,33 +511,8 @@ pub fn handle( let canonical_contract_address = to_canonical(contract_address)?; - // contract_key is unique for each contract - // it's used in state encryption to prevent the same - // encryption keys from being used for different contracts - let mut contract_key = base_env.get_current_contract_key()?; - validate_contract_key(&contract_key, &canonical_contract_address, &contract_code)?; - - if base_env.was_migrated() { - println!("Contract was migrated, validating proof"); - - // was_migrated checks that these won't fail - let og_contract_key = base_env.get_original_contract_key()?; - let sent_contract_key_proof = base_env.get_contract_key_proof()?; - - let contract_key_proof = generate_contract_key_proof( - &canonical_contract_address.0 .0, - &contract_code.hash(), - &og_contract_key, - &contract_key, // this is already validated - ); - - if sent_contract_key_proof != contract_key_proof { - error!("Failed to validate contract key proof for a migrated contract"); - return Err(EnclaveError::ValidationFailure); - } - - contract_key = og_contract_key; // used in engine for state encryption - } + let og_contract_key = + validate_contract_key(&base_env, &canonical_contract_address, &contract_code)?; let parsed_sig_info: SigInfo = extract_sig_info(sig_info)?; @@ -619,7 +575,7 @@ pub fn handle( context, gas_limit, &contract_code, - &contract_key, + &og_contract_key, ContractOperation::Handle, query_depth, secret_msg.nonce, @@ -655,7 +611,12 @@ pub fn handle( } #[cfg(feature = "random")] - set_random_in_env(block_height, &contract_key, &mut engine, &mut versioned_env); + set_random_in_env( + block_height, + &og_contract_key, + &mut engine, + &mut versioned_env, + ); versioned_env.set_contract_hash(&contract_hash); @@ -750,9 +711,8 @@ pub fn query( let canonical_contract_address = to_canonical(contract_address)?; - let contract_key = base_env.get_current_contract_key()?; - - validate_contract_key(&contract_key, &canonical_contract_address, &contract_code)?; + let og_contract_key = + validate_contract_key(&base_env, &canonical_contract_address, &contract_code)?; let secret_msg = SecretMessage::from_slice(msg)?; let decrypted_msg = secret_msg.decrypt()?; @@ -764,7 +724,7 @@ pub fn query( context, gas_limit, &contract_code, - &contract_key, + &og_contract_key, ContractOperation::Query, query_depth, secret_msg.nonce, diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index 449354b83..aa7c73bcc 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -2,7 +2,6 @@ use cw_types_v1::ibc::IbcPacketReceiveMsg; use cw_types_v1::results::REPLY_ENCRYPTION_MAGIC_BYTES; use log::*; -#[cfg(feature = "light-client-validation")] use cw_types_generic::BaseEnv; use cw_types_v010::types::{CanonicalAddr, Coin, HumanAddr}; @@ -154,7 +153,7 @@ pub fn generate_contract_id( authentication_key.sign_sha_256(&input_data) } -pub fn validate_contract_key( +pub fn validate_current_contract_key( contract_key: &[u8; CONTRACT_KEY_LENGTH], contract_address: &CanonicalAddr, contract_code: &ContractCode, @@ -193,6 +192,66 @@ pub fn validate_contract_key( } } +/// validate_contract_key validates the contract key against the contract address and code hash. If the contract was previously migrated, it also validates the contract key proof against the original contract key. +pub fn validate_contract_key( + base_env: &BaseEnv, + canonical_contract_address: &CanonicalAddr, + contract_code: &ContractCode, +) -> Result<[u8; CONTRACT_KEY_LENGTH], EnclaveError> { + let current_contract_key: [u8; CONTRACT_KEY_LENGTH] = base_env.get_current_contract_key()?; + + validate_current_contract_key( + ¤t_contract_key, + canonical_contract_address, + contract_code, + )?; + + if base_env.was_migrated() { + println!("Contract was migrated, validating proof"); + + let og_contract_key: [u8; CONTRACT_KEY_LENGTH] = base_env.get_original_contract_key()?; + let sent_contract_key_proof = base_env.get_contract_key_proof()?; + + let contract_key_proof = generate_contract_key_proof( + &canonical_contract_address.0 .0, + &contract_code.hash(), + &og_contract_key, + ¤t_contract_key, // this is already validated + ); + + if sent_contract_key_proof != contract_key_proof { + error!("Failed to validate contract key proof for a migrated contract"); + return Err(EnclaveError::ValidationFailure); + } + + // og_contract_key is always used in engine for state encryption + Ok(og_contract_key) + } else { + // og_contract_key is always used in engine for state encryption + // contract wasn't previously migrated, thus og_contract_key == current_contract_key + Ok(current_contract_key) + } +} + +pub fn generate_contract_key_proof( + contract_address: &[u8], + code_hash: &[u8], + prev_contract_key: &[u8], + new_contract_key: &[u8], +) -> [u8; enclave_crypto::HASH_SIZE] { + let mut data_to_hash = vec![]; + data_to_hash.extend_from_slice(contract_address); + data_to_hash.extend_from_slice(code_hash); + data_to_hash.extend_from_slice(prev_contract_key); + data_to_hash.extend_from_slice(new_contract_key); + + let contract_key_proof_secret = KEY_MANAGER.get_contract_key_proof_secret().unwrap(); + + data_to_hash.extend_from_slice(contract_key_proof_secret.get()); + + sha_256(&data_to_hash) +} + pub struct ValidatedMessage { pub validated_msg: Vec, pub reply_params: Option>, From a499efe0af4fc10a47a57b7215378f706331973d Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 27 Jun 2023 14:00:01 +0300 Subject: [PATCH 048/164] Fix CI Updated CI to use `make build-test-contracts` instead of `make build-test-contract` --- .github/workflows/ci.yaml | 2 +- deployment/dockerfiles/tests/system-tests.Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 635a62752..39980da6a 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -71,7 +71,7 @@ jobs: ./scripts/install-wasm-tools.sh - name: Build Contracts run: | - make build-test-contract + make build-test-contracts cp x/compute/internal/keeper/testdata/erc20.wasm . - uses: actions/upload-artifact@v3 with: diff --git a/deployment/dockerfiles/tests/system-tests.Dockerfile b/deployment/dockerfiles/tests/system-tests.Dockerfile index fcbd1ea94..a2108e277 100644 --- a/deployment/dockerfiles/tests/system-tests.Dockerfile +++ b/deployment/dockerfiles/tests/system-tests.Dockerfile @@ -11,7 +11,7 @@ COPY cosmwasm cosmwasm COPY Makefile . COPY x x -RUN . /root/.cargo/env && make build-test-contract +RUN . /root/.cargo/env && make build-test-contracts # Add source files COPY go-cosmwasm go-cosmwasm From bfb09df94a45b56dca1cd11344e4356255803d2e Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 28 Jun 2023 09:40:56 +0300 Subject: [PATCH 049/164] Copy all exec tests and modify to test after migrate --- .vscode/settings.json | 1 + Makefile | 2 + .../test-compute-contract-v2/.gitignore | 13 + .../test-compute-contract-v2/Cargo.lock | 712 +++++ .../test-compute-contract-v2/Cargo.toml | 43 + .../test-compute-contract-v2/Makefile | 8 + .../test-compute-contract-v2/rust-toolchain | 1 + .../test-compute-contract-v2/src/contract.rs | 2709 +++++++++++++++++ .../test-compute-contract-v2/src/lib.rs | 3 + .../test-compute-contract-v2/src/msg.rs | 509 ++++ .../test-compute-contract-v2/src/state.rs | 23 + go-cosmwasm/types/stderror.go | 17 + .../keeper/secret_contracts_migrate_test.go | 2542 +++++++++++++++- x/compute/internal/keeper/test_common.go | 2 + .../keeper/testdata/v1-contract-v2.wasm | Bin 0 -> 1894770 bytes 15 files changed, 6579 insertions(+), 6 deletions(-) create mode 100644 cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/.gitignore create mode 100644 cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Cargo.lock create mode 100644 cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Cargo.toml create mode 100644 cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Makefile create mode 100644 cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/rust-toolchain create mode 100644 cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/contract.rs create mode 100644 cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/lib.rs create mode 100644 cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/msg.rs create mode 100644 cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/state.rs create mode 100755 x/compute/internal/keeper/testdata/v1-contract-v2.wasm diff --git a/.vscode/settings.json b/.vscode/settings.json index 100ae5511..9673e3378 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,6 +7,7 @@ "third_party/build/Cargo.toml", "cosmwasm/enclaves/Cargo.toml", "cosmwasm/contracts/v1/compute-tests/test-compute-contract/Cargo.toml", + "cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Cargo.toml", "cosmwasm/contracts/v1/compute-tests/ibc-test-contract/Cargo.toml", "cosmwasm/contracts/v1/compute-tests/bench-contract/Cargo.toml", "cosmwasm/contracts/v010/compute-tests/test-compute-contract/Cargo.toml", diff --git a/Makefile b/Makefile index d1079c19d..8f959a130 100644 --- a/Makefile +++ b/Makefile @@ -424,6 +424,8 @@ build-test-contracts: cp $(TEST_CONTRACT_V010_PATH)/test-compute-contract/*.wasm $(TEST_COMPUTE_MODULE_PATH)/ $(MAKE) -C $(TEST_CONTRACT_V1_PATH)/test-compute-contract cp $(TEST_CONTRACT_V1_PATH)/test-compute-contract/*.wasm $(TEST_COMPUTE_MODULE_PATH)/ + $(MAKE) -C $(TEST_CONTRACT_V1_PATH)/test-compute-contract-v2 + cp $(TEST_CONTRACT_V1_PATH)/test-compute-contract-v2/*.wasm $(TEST_COMPUTE_MODULE_PATH)/ $(MAKE) -C $(TEST_CONTRACT_V1_PATH)/ibc-test-contract cp $(TEST_CONTRACT_V1_PATH)/ibc-test-contract/*.wasm $(TEST_COMPUTE_MODULE_PATH)/ $(MAKE) -C $(TEST_CONTRACT_V1_PATH)/migration/contract-v1 diff --git a/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/.gitignore b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/.gitignore new file mode 100644 index 000000000..0e24e33d5 --- /dev/null +++ b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/.gitignore @@ -0,0 +1,13 @@ +# Build results +/target +*.wasm + +# Text file backups +**/*.rs.bk + +# macOS +.DS_Store + +# IDEs +*.iml +.idea diff --git a/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Cargo.lock b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Cargo.lock new file mode 100644 index 000000000..11b7d58ea --- /dev/null +++ b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Cargo.lock @@ -0,0 +1,712 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bincode2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f49f6183038e081170ebbbadee6678966c7d54728938a3e7de7f4e780770318f" +dependencies = [ + "byteorder", + "serde", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "const-oid" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" + +[[package]] +name = "cosmwasm-crypto" +version = "1.1.9" +source = "git+https://github.com/scrtlabs/cosmwasm?rev=46a0be1de3b3c4f45d502d31cd08c258598c54be#46a0be1de3b3c4f45d502d31cd08c258598c54be" +dependencies = [ + "digest 0.10.6", + "ed25519-zebra", + "k256", + "rand_core 0.6.4", + "thiserror", +] + +[[package]] +name = "cosmwasm-derive" +version = "1.1.9" +source = "git+https://github.com/scrtlabs/cosmwasm?rev=46a0be1de3b3c4f45d502d31cd08c258598c54be#46a0be1de3b3c4f45d502d31cd08c258598c54be" +dependencies = [ + "syn 1.0.109", +] + +[[package]] +name = "cosmwasm-std" +version = "1.1.9" +source = "git+https://github.com/scrtlabs/cosmwasm?rev=46a0be1de3b3c4f45d502d31cd08c258598c54be#46a0be1de3b3c4f45d502d31cd08c258598c54be" +dependencies = [ + "base64", + "cosmwasm-crypto", + "cosmwasm-derive", + "derivative", + "forward_ref", + "hex", + "schemars", + "serde", + "serde-json-wasm 0.4.1", + "thiserror", + "uint", +] + +[[package]] +name = "cosmwasm-storage" +version = "1.1.9" +source = "git+https://github.com/scrtlabs/cosmwasm?rev=46a0be1de3b3c4f45d502d31cd08c258598c54be#46a0be1de3b3c4f45d502d31cd08c258598c54be" +dependencies = [ + "cosmwasm-std", + "serde", +] + +[[package]] +name = "cpufeatures" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181" +dependencies = [ + "libc", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer 0.10.4", + "crypto-common", + "subtle", +] + +[[package]] +name = "dyn-clone" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30" + +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der", + "elliptic-curve", + "rfc6979", + "signature", +] + +[[package]] +name = "ed25519-zebra" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c24f403d068ad0b359e577a77f92392118be3f3c927538f2bb544a5ecd828c6" +dependencies = [ + "curve25519-dalek", + "hashbrown", + "hex", + "rand_core 0.6.4", + "serde", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct", + "crypto-bigint", + "der", + "digest 0.10.6", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "forward_ref" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.6", +] + +[[package]] +name = "itoa" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" + +[[package]] +name = "k256" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "sha2 0.10.6", +] + +[[package]] +name = "libc" +version = "0.2.140" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" + +[[package]] +name = "once_cell" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "proc-macro2" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint", + "hmac", + "zeroize", +] + +[[package]] +name = "ryu" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" + +[[package]] +name = "schemars" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02c613288622e5f0c3fdc5dbd4db1c5fbe752746b1d1a56a0630b78fd00de44f" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "109da1e6b197438deb6db99952990c7f959572794b80ff93707d55a232545e7c" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 1.0.109", +] + +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "secp256k1" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "295642060261c80709ac034f52fca8e5a9fa2c7d341ded5cdb164b7c33768b2a" +dependencies = [ + "secp256k1-sys", +] + +[[package]] +name = "secp256k1-sys" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "152e20a0fd0519390fc43ab404663af8a0b794273d2a91d60ad4a39f13ffe110" +dependencies = [ + "cc", +] + +[[package]] +name = "serde" +version = "1.0.159" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-json-wasm" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120bad73306616e91acd7ceed522ba96032a51cffeef3cc813de7f367df71e37" +dependencies = [ + "serde", +] + +[[package]] +name = "serde-json-wasm" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.159" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.13", +] + +[[package]] +name = "serde_derive_internals" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "serde_json" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.6", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest 0.10.6", + "rand_core 0.6.4", +] + +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c9da457c5285ac1f936ebd076af6dac17a61cfe7826f2076b4d015cf47bc8ec" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.13", +] + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unicode-ident" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" + +[[package]] +name = "v1-sanity-contract-v2" +version = "0.0.1" +dependencies = [ + "bincode2", + "cosmwasm-std", + "cosmwasm-storage", + "schemars", + "secp256k1", + "serde", + "serde-json-wasm 0.2.3", +] + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "zeroize" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Cargo.toml b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Cargo.toml new file mode 100644 index 000000000..7683e26e7 --- /dev/null +++ b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Cargo.toml @@ -0,0 +1,43 @@ +[package] +name = "v1-sanity-contract-v2" +version = "0.0.1" +authors = ["Enigma "] +edition = "2018" +description = "A Test contract intended to use in system tests for the Secret Netowrk" +license = "MIT" +exclude = [ + # Those files are cosmwasm-opt artifacts. You might want to commit them for convenience but they should not be part of the source code publication. + "v1-sanity-contract.wasm", +] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +crate-type = ["cdylib", "rlib"] + +[profile.release] +opt-level = 3 +debug = false +rpath = false +lto = true +debug-assertions = false +codegen-units = 1 +panic = 'abort' +incremental = false +overflow-checks = true + +[features] +default = [] +backtraces = ["cosmwasm-std/backtraces"] +with_floats = [] + +[dependencies] +cosmwasm-std = { git = "https://github.com/scrtlabs/cosmwasm", rev = "46a0be1de3b3c4f45d502d31cd08c258598c54be", package = "cosmwasm-std" } +cosmwasm-storage = { git = "https://github.com/scrtlabs/cosmwasm", rev = "46a0be1de3b3c4f45d502d31cd08c258598c54be", package = "cosmwasm-storage" } +schemars = "0.8.1" +serde = { version = "1.0.114", default-features = false, features = [ + "derive", + "alloc" +] } +serde-json-wasm = "0.2.1" +secp256k1 = "0.22.2" +bincode2 = "2.0.1" diff --git a/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Makefile b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Makefile new file mode 100644 index 000000000..df63c622c --- /dev/null +++ b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Makefile @@ -0,0 +1,8 @@ +all: src/contract.rs src src src Cargo.toml Cargo.lock + rustup target add wasm32-unknown-unknown + RUSTFLAGS='-C link-arg=-s' cargo build --release --target wasm32-unknown-unknown + cp ./target/wasm32-unknown-unknown/release/v1_sanity_contract_v2.wasm ./v1-contract-v2.wasm + +clean: + cargo clean + -rm -f ./v1-contract.wasm diff --git a/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/rust-toolchain b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/rust-toolchain new file mode 100644 index 000000000..a7efc46ca --- /dev/null +++ b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/rust-toolchain @@ -0,0 +1 @@ +1.61 \ No newline at end of file diff --git a/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/contract.rs b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/contract.rs new file mode 100644 index 000000000..c30cefb06 --- /dev/null +++ b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/contract.rs @@ -0,0 +1,2709 @@ +use core::time; +use mem::MaybeUninit; +use std::{mem, thread, vec}; + +use cosmwasm_std::{ + attr, coins, entry_point, to_binary, BankMsg, Binary, CosmosMsg, Deps, DepsMut, Empty, Env, + Event, MessageInfo, QueryRequest, Reply, ReplyOn, Response, StdError, StdResult, Storage, + SubMsg, SubMsgResult, WasmMsg, WasmQuery, +}; +use cosmwasm_storage::PrefixedStorage; +use secp256k1::Secp256k1; + +use crate::msg::{ + ExecuteMsg, ExternalMessages, IBCLifecycleComplete, InstantiateMsg, MigrateMsg, QueryMsg, + QueryRes, +}; +use crate::state::{count, count_read, expiration, expiration_read, PREFIX_TEST, TEST_KEY}; + +#[entry_point] +pub fn instantiate( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: InstantiateMsg, +) -> StdResult { + match msg { + InstantiateMsg::WasmMsg { ty } => wasm_msg(ty), + InstantiateMsg::Counter { counter, expires } => { + if counter == 0 { + return Err(StdError::generic_err("got wrong counter on init")); + } + + count(deps.storage).save(&counter)?; + let expires = env.block.height + expires; + expiration(deps.storage).save(&expires)?; + let mut resp = Response::default(); + resp.data = Some(env.contract.address.as_bytes().into()); + Ok(resp) + } + + InstantiateMsg::AddAttributes {} => Ok(Response::new() + .add_attribute("attr1", "🦄") + .add_attribute("attr2", "🌈")), + InstantiateMsg::AddAttributesWithSubmessage { id } => Ok(Response::new() + .add_submessage(SubMsg { + id, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: env.contract.code_hash, + contract_addr: env.contract.address.into_string(), + msg: Binary::from(r#"{"add_more_attributes":{}}"#.as_bytes().to_vec()), + funds: vec![], + }) + .into(), + reply_on: match id { + 0 => ReplyOn::Never, + _ => ReplyOn::Always, + }, + gas_limit: None, + }) + .add_attribute("attr1", "🦄") + .add_attribute("attr2", "🌈")), + + InstantiateMsg::AddPlaintextAttributes {} => Ok(Response::new() + .add_attribute_plaintext("attr1", "🦄") + .add_attribute_plaintext("attr2", "🌈")), + InstantiateMsg::AddPlaintextAttributesWithSubmessage { id } => Ok(Response::new() + .add_submessage(SubMsg { + id, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: env.contract.code_hash, + contract_addr: env.contract.address.into_string(), + msg: Binary::from( + r#"{"add_more_plaintext_attributes":{}}"#.as_bytes().to_vec(), + ), + funds: vec![], + }) + .into(), + reply_on: match id { + 0 => ReplyOn::Never, + _ => ReplyOn::Always, + }, + gas_limit: None, + }) + .add_attribute_plaintext("attr1", "🦄") + .add_attribute_plaintext("attr2", "🌈")), + + InstantiateMsg::AddEvents {} => Ok(Response::new() + .add_event( + Event::new("cyber1".to_string()) + .add_attribute("attr1", "🦄") + .add_attribute("attr2", "🌈"), + ) + .add_event( + Event::new("cyber2".to_string()) + .add_attribute("attr3", "🐙") + .add_attribute("attr4", "🦄"), + )), + InstantiateMsg::AddEventsWithSubmessage { id } => Ok(Response::new() + .add_submessage(SubMsg { + id, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: env.contract.code_hash, + contract_addr: env.contract.address.into_string(), + msg: Binary::from(r#"{"add_more_events":{}}"#.as_bytes().to_vec()), + funds: vec![], + }) + .into(), + reply_on: match id { + 0 => ReplyOn::Never, + _ => ReplyOn::Always, + }, + gas_limit: None, + }) + .add_event( + Event::new("cyber1".to_string()) + .add_attribute("attr1", "🦄") + .add_attribute("attr2", "🌈"), + ) + .add_event( + Event::new("cyber2".to_string()) + .add_attribute("attr3", "🐙") + .add_attribute("attr4", "🦄"), + )), + InstantiateMsg::AddMixedAttributesAndEvents {} => Ok(Response::new() + .add_event( + Event::new("cyber1".to_string()) + .add_attribute_plaintext("attr1", "🦄") + .add_attribute_plaintext("attr2", "🌈"), + ) + .add_attribute_plaintext("attr3", "🐙") + .add_attribute_plaintext("attr4", "🦄")), + InstantiateMsg::AddMixedAttributesAndEventsWithSubmessage { id } => Ok(Response::new() + .add_submessage(SubMsg { + id, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: env.contract.code_hash, + contract_addr: env.contract.address.into_string(), + msg: Binary::from( + r#"{"add_more_mixed_attributes_and_events":{}}"#.as_bytes().to_vec(), + ), + funds: vec![], + }) + .into(), + reply_on: match id { + 0 => ReplyOn::Never, + _ => ReplyOn::Always, + }, + gas_limit: None, + }) + .add_event( + Event::new("cyber1".to_string()) + .add_attribute("attr1", "🦄") + .add_attribute("attr2", "🌈"), + ) + .add_attribute("attr3", "🐙") + .add_attribute_plaintext("attr4", "🦄")), + + InstantiateMsg::MeasureGasForSubmessage { id } => { + let msg = match id { + 0 => Binary::from(r#"{"gas_meter":{}}"#.as_bytes().to_vec()), + _ => Binary::from(r#"{"gas_meter_proxy":{}}"#.as_bytes().to_vec()), + }; + + Ok(Response::new().add_submessage(SubMsg { + id, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: env.contract.code_hash, + contract_addr: env.contract.address.into_string(), + msg, + funds: vec![], + }) + .into(), + reply_on: match id { + 0 => ReplyOn::Never, + _ => ReplyOn::Always, + }, + gas_limit: None, + })) + } + // These were ported from the v0.10 test-contract: + InstantiateMsg::Nop {} => Ok(Response::new().add_attribute("init", "🌈")), + InstantiateMsg::Callback { + contract_addr, + code_hash, + } => Ok(Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + code_hash, + contract_addr: contract_addr.clone(), + msg: Binary::from(r#"{"c":{"x":0,"y":13}}"#.as_bytes().to_vec()), + funds: vec![], + })) + .add_attribute("init with a callback", "🦄")), + InstantiateMsg::CallbackContractError { + contract_addr, + code_hash, + } => Ok(Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: contract_addr.clone(), + code_hash, + msg: Binary::from(r#"{"contract_error":{"error_type":"generic_err"}}"#.as_bytes()), + funds: vec![], + })) + .add_attribute("init with a callback with contract error", "🤷‍♀️")), + InstantiateMsg::ContractError { error_type } => Err(map_string_to_error(error_type)), + InstantiateMsg::NoLogs {} => Ok(Response::new()), + InstantiateMsg::CallbackToInit { code_id, code_hash } => Ok(Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Instantiate { + code_id, + msg: Binary::from(r#"{"nop":{}}"#.as_bytes().to_vec()), + code_hash, + funds: vec![], + label: String::from("fi"), + })) + .add_attribute("instantiating a new contract from init!", "🐙")), + InstantiateMsg::CallbackBadParams { + contract_addr, + code_hash, + } => Ok( + Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: contract_addr.clone(), + code_hash, + msg: Binary::from(r#"{"c":{"x":"banana","y":3}}"#.as_bytes().to_vec()), + funds: vec![], + })), + ), + InstantiateMsg::Panic {} => panic!("panic in init"), + InstantiateMsg::SendExternalQueryDepthCounter { + to, + depth, + code_hash, + } => Ok(Response::new().add_attribute( + format!( + "{}", + send_external_query_depth_counter(deps.as_ref(), to, depth, code_hash) + ), + "", + )), + InstantiateMsg::SendExternalQueryRecursionLimit { + to, + depth, + code_hash, + } => Ok(Response::new().add_attribute( + "message", + send_external_query_recursion_limit(deps.as_ref(), to, depth, code_hash)?, + )), + InstantiateMsg::CallToInit { + code_id, + code_hash, + label, + msg, + } => Ok(Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Instantiate { + code_id, + code_hash, + msg: Binary(msg.as_bytes().into()), + funds: vec![], + label, + })) + .add_attribute("a", "a")), + InstantiateMsg::CallToExec { + addr, + code_hash, + msg, + } => Ok(Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: addr, + code_hash, + msg: Binary(msg.as_bytes().into()), + funds: vec![], + })) + .add_attribute("b", "b")), + InstantiateMsg::CallToQuery { + addr, + code_hash, + msg, + } => { + let answer: u32 = deps + .querier + .query(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr: addr, + code_hash, + msg: Binary::from(msg.as_bytes().to_vec()), + })) + .map_err(|err| { + StdError::generic_err(format!("Got an error from query: {:?}", err)) + })?; + + Ok(Response::new().add_attribute("c", format!("{}", answer))) + } + InstantiateMsg::BankMsgSend { to, amount } => { + Ok(Response::new().add_message(CosmosMsg::Bank(BankMsg::Send { + to_address: to, + amount, + }))) + } + InstantiateMsg::BankMsgBurn { amount } => { + Ok(Response::new().add_message(CosmosMsg::Bank(BankMsg::Burn { amount }))) + } + InstantiateMsg::CosmosMsgCustom {} => { + Ok(Response::new().add_message(CosmosMsg::Custom(Empty {}))) + } + InstantiateMsg::SendMultipleFundsToInitCallback { + coins, + code_id, + code_hash, + } => Ok( + Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Instantiate { + code_id, + code_hash, + msg: Binary("{\"nop\":{}}".as_bytes().to_vec()), + funds: coins, + label: "init test".to_string(), + })), + ), + InstantiateMsg::SendMultipleFundsToExecCallback { + coins, + to, + code_hash, + } => Ok( + Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: to, + code_hash, + msg: Binary("{\"no_data\":{}}".as_bytes().to_vec()), + funds: coins, + })), + ), + InstantiateMsg::GetEnv {} => Ok(Response::new() + .add_attribute("env", serde_json_wasm::to_string(&env).unwrap()) + .add_attribute("info", serde_json_wasm::to_string(&info).unwrap())), + InstantiateMsg::TestRemoveDb {} => { + let mut store = PrefixedStorage::new(deps.storage, PREFIX_TEST); + // save something + store.set( + TEST_KEY, + &bincode2::serialize(&true) + .map_err(|_| StdError::generic_err("serialization error"))?, + ); + + store.remove(TEST_KEY); + // test if it was removed + if store.get(TEST_KEY).is_some() { + return Err(StdError::generic_err("This key should have been removed!")); + } + + Ok(Response::new()) + } + } +} + +pub fn wasm_msg(ty: String) -> StdResult { + if ty == "success" { + return Ok(Response::default()); + } else if ty == "err" { + return Err(StdError::generic_err("custom error")); + } else if ty == "panic" { + panic!() + } + + return Err(StdError::generic_err("custom error")); +} + +#[entry_point] +pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> StdResult { + match msg { + ExecuteMsg::IncrementTimes { times } => { + let mut res = Response::default(); + for _ in 0..times { + res = res.add_message(CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: env.contract.code_hash.clone(), + contract_addr: env.contract.address.clone().into_string(), + msg: Binary::from("{\"increment\":{\"addition\":1}}".as_bytes().to_vec()), + funds: vec![], + })); + } + Ok(res) + } + ExecuteMsg::LastMsgMarkerNop {} => { + // also tests using finalize like this + Ok(Response::new().add_message(CosmosMsg::FinalizeTx(Empty {}))) + } + ExecuteMsg::LastMsgMarker {} => { + let increment_msg = SubMsg { + id: 0, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: env.contract.code_hash, + contract_addr: env.contract.address.into_string(), + msg: Binary::from("{\"increment\":{\"addition\":1}}".as_bytes().to_vec()), + funds: vec![], + }) + .into(), + reply_on: ReplyOn::Never, + gas_limit: None, + }; + + let bank_msg = SubMsg { + id: 0, + msg: CosmosMsg::Bank(BankMsg::Send { + to_address: "".to_string(), + amount: coins(1u128, "ust"), + }) + .into(), + reply_on: ReplyOn::Never, + gas_limit: None, + }; + Ok(Response::new() + .add_submessages(vec![ + increment_msg.clone(), + increment_msg.clone(), + increment_msg.clone(), + increment_msg.clone(), + ]) + // also tests using finalize like this + .add_message(CosmosMsg::finalize_tx()) + .add_submessages(vec![increment_msg.clone(), bank_msg.clone()])) + } + ExecuteMsg::WasmMsg { ty } => wasm_msg(ty), + ExecuteMsg::Increment { addition } => increment(env, deps, addition), + ExecuteMsg::SendFundsWithErrorWithReply {} => Ok(Response::new() + .add_submessage(SubMsg { + id: 8000, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: env.contract.code_hash, + contract_addr: env.contract.address.into_string(), + msg: Binary::from(r#"{"add_more_attributes":{}}"#.as_bytes().to_vec()), + funds: coins(100, "lior"), + }) + .into(), + reply_on: ReplyOn::Always, + gas_limit: None, + }) + .add_attribute("attr1", "🦄") + .add_attribute("attr2", "🌈")), + ExecuteMsg::SendFundsWithReply {} => Ok(Response::new() + .add_submessage(SubMsg { + id: 8001, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: env.contract.code_hash, + contract_addr: env.contract.address.into_string(), + msg: Binary::from(r#"{"add_more_attributes":{}}"#.as_bytes().to_vec()), + funds: coins(100, "denom"), + }) + .into(), + reply_on: ReplyOn::Always, + gas_limit: None, + }) + .add_attribute("attr1", "🦄") + .add_attribute("attr2", "🌈")), + ExecuteMsg::AddAttributes {} => Ok(Response::new() + .add_attribute("attr1", "🦄") + .add_attribute("attr2", "🌈")), + ExecuteMsg::AddAttributesWithSubmessage { id } => Ok(Response::new() + .add_submessage(SubMsg { + id, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: env.contract.code_hash, + contract_addr: env.contract.address.into_string(), + msg: Binary::from(r#"{"add_more_attributes":{}}"#.as_bytes().to_vec()), + funds: vec![], + }) + .into(), + reply_on: match id { + 0 => ReplyOn::Never, + _ => ReplyOn::Always, + }, + gas_limit: None, + }) + .add_attribute("attr1", "🦄") + .add_attribute("attr2", "🌈")), + ExecuteMsg::AddMoreAttributes {} => Ok(Response::new() + .add_attribute("attr3", "🍉") + .add_attribute("attr4", "🥝")), + ExecuteMsg::AddPlaintextAttributes {} => Ok(Response::new() + .add_attribute_plaintext("attr1", "🦄") + .add_attribute_plaintext("attr2", "🌈")), + ExecuteMsg::AddPlaintextAttributesWithSubmessage { id } => Ok(Response::new() + .add_submessage(SubMsg { + id, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: env.contract.code_hash, + contract_addr: env.contract.address.into_string(), + msg: Binary::from( + r#"{"add_more_plaintext_attributes":{}}"#.as_bytes().to_vec(), + ), + funds: vec![], + }) + .into(), + reply_on: match id { + 0 => ReplyOn::Never, + _ => ReplyOn::Always, + }, + gas_limit: None, + }) + .add_attribute_plaintext("attr1", "🦄") + .add_attribute_plaintext("attr2", "🌈")), + ExecuteMsg::AddMorePlaintextAttributes {} => Ok(Response::new() + .add_attribute_plaintext("attr3", "🍉") + .add_attribute_plaintext("attr4", "🥝")), + + ExecuteMsg::AddEvents {} => Ok(Response::new() + .add_event( + Event::new("cyber1".to_string()) + .add_attribute("attr1", "🦄") + .add_attribute("attr2", "🌈"), + ) + .add_event( + Event::new("cyber2".to_string()) + .add_attribute("attr3", "🐙") + .add_attribute("attr4", "🦄"), + )), + ExecuteMsg::AddEventsWithSubmessage { id } => Ok(Response::new() + .add_submessage(SubMsg { + id, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: env.contract.code_hash, + contract_addr: env.contract.address.into_string(), + msg: Binary::from(r#"{"add_more_events":{}}"#.as_bytes().to_vec()), + funds: vec![], + }) + .into(), + reply_on: match id { + 0 => ReplyOn::Never, + _ => ReplyOn::Always, + }, + gas_limit: None, + }) + .add_event( + Event::new("cyber1".to_string()) + .add_attribute("attr1", "🦄") + .add_attribute("attr2", "🌈"), + ) + .add_event( + Event::new("cyber2".to_string()) + .add_attribute("attr3", "🐙") + .add_attribute("attr4", "🦄"), + )), + ExecuteMsg::AddMoreEvents {} => Ok(Response::new() + .add_event( + Event::new("cyber3".to_string()) + .add_attribute("attr1", "🤯") + .add_attribute("attr2", "🤟"), + ) + .add_event( + Event::new("cyber4".to_string()) + .add_attribute("attr3", "😅") + .add_attribute("attr4", "🦄"), + )), + + ExecuteMsg::AddMixedAttributesAndEvents {} => Ok(Response::new() + .add_event( + Event::new("cyber1".to_string()) + .add_attribute_plaintext("attr1", "🦄") + .add_attribute_plaintext("attr2", "🌈"), + ) + .add_attribute_plaintext("attr3", "🐙") + .add_attribute_plaintext("attr4", "🦄")), + ExecuteMsg::AddMixedAttributesAndEventsWithSubmessage { id } => Ok(Response::new() + .add_submessage(SubMsg { + id, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: env.contract.code_hash, + contract_addr: env.contract.address.into_string(), + msg: Binary::from( + r#"{"add_more_mixed_attributes_and_events":{}}"#.as_bytes().to_vec(), + ), + funds: vec![], + }) + .into(), + reply_on: match id { + 0 => ReplyOn::Never, + _ => ReplyOn::Always, + }, + gas_limit: None, + }) + .add_event( + Event::new("cyber1".to_string()) + .add_attribute("attr1", "🦄") + .add_attribute("attr2", "🌈"), + ) + .add_attribute("attr3", "🐙") + .add_attribute_plaintext("attr4", "🦄")), + ExecuteMsg::AddMoreMixedAttributesAndEvents {} => Ok(Response::new() + .add_event( + Event::new("cyber2".to_string()) + .add_attribute("attr5", "🐙") + .add_attribute("attr6", "🦄"), + ) + .add_attribute("attr7", "😅") + .add_attribute_plaintext("attr8", "🦄")), + ExecuteMsg::AddAttributesFromV010 { + addr, + code_hash, + id, + } => Ok(Response::new() + .add_submessage(SubMsg { + id, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash, + contract_addr: addr, + msg: Binary::from(r#"{"add_more_attributes":{}}"#.as_bytes().to_vec()), + funds: vec![], + }) + .into(), + reply_on: match id { + 0 => ReplyOn::Never, + _ => ReplyOn::Always, + }, + gas_limit: None, + }) + .add_event( + Event::new("cyber1".to_string()) + .add_attribute("attr1", "🦄") + .add_attribute("attr2", "🌈"), + ) + .add_attribute("attr3", "🐙") + .add_attribute_plaintext("attr4", "🦄")), + ExecuteMsg::GasMeter {} => { + // busy work + let mut v = vec![0; 65536]; + let mut x = 0; + loop { + x += (x + 1) % 65536; + v[x] = 65536 - x; + } + } + ExecuteMsg::GasMeterProxy {} => Ok(Response::default()), + ExecuteMsg::TransferMoney { amount } => transfer_money(deps, amount), + ExecuteMsg::RecursiveReply {} => recursive_reply(env, deps), + ExecuteMsg::RecursiveReplyFail {} => recursive_reply_fail(env, deps), + ExecuteMsg::InitNewContract {} => init_new_contract(env, deps), + ExecuteMsg::InitNewContractWithError {} => init_new_contract_with_error(env, deps), + ExecuteMsg::SubMsgLoop { iter } => sub_msg_loop(env, deps, iter), + ExecuteMsg::SubMsgLoopIner { iter } => sub_msg_loop_iner(env, deps, iter), + ExecuteMsg::MultipleSubMessages {} => send_multiple_sub_messages(env, deps), + ExecuteMsg::MultipleSubMessagesNoReply {} => send_multiple_sub_messages_no_reply(env, deps), + ExecuteMsg::QuickError {} => { + count(deps.storage).save(&123456)?; + Err(StdError::generic_err("error in execute")) + } + ExecuteMsg::MultipleSubMessagesNoReplyWithError {} => { + send_multiple_sub_messages_no_reply_with_error(env, deps) + } + ExecuteMsg::MultipleSubMessagesNoReplyWithPanic {} => { + send_multiple_sub_messages_no_reply_with_panic(env, deps) + } + ExecuteMsg::MultipleSubMessagesWithReplyWithError {} => { + send_multiple_sub_messages_with_reply_with_error(env, deps) + } + ExecuteMsg::MultipleSubMessagesWithReplyWithPanic {} => { + send_multiple_sub_messages_with_reply_with_panic(env, deps) + } + ExecuteMsg::InitV10 { + counter, + code_id, + code_hash, + } => { + let mut resp = Response::default(); + + let msg = + "{\"init_from_v1\":{\"counter\":".to_string() + counter.to_string().as_str() + "}}"; + resp.messages.push(SubMsg { + id: 1700, + msg: CosmosMsg::Wasm(WasmMsg::Instantiate { + code_hash, + msg: Binary::from(msg.as_bytes().to_vec()), + funds: vec![], + label: "new2231231".to_string(), + code_id, + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Always, + }); + + Ok(resp) + } + ExecuteMsg::ExecV10 { address, code_hash } => { + let mut resp = Response::default(); + + resp.messages.push(SubMsg { + id: 1800, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + msg: Binary::from("{\"execute_from_v1\":{\"counter\":20}}".as_bytes().to_vec()), + contract_addr: address, + code_hash, + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Always, + }); + + Ok(resp) + } + ExecuteMsg::AddAttributeStep1 {} => Ok(Response::new() + .add_submessage(SubMsg { + id: 8451, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + msg: Binary("{\"add_attribute_step2\":{}}".as_bytes().to_vec()), + contract_addr: env.contract.address.into_string(), + code_hash: env.contract.code_hash, + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Success, + }) + .add_attribute_plaintext("attr1", "🦄") + .set_data(to_binary("step1")?)), + ExecuteMsg::AddAttributeStep2 {} => Ok(Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + msg: Binary("{\"add_attribute_step3\":{}}".as_bytes().to_vec()), + contract_addr: env.contract.address.into_string(), + code_hash: env.contract.code_hash, + funds: vec![], + })) + .add_attribute_plaintext("attr2", "🦄") + .set_data(to_binary("step2")?)), + ExecuteMsg::AddAttributeStep3 {} => Ok(Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + msg: Binary("{\"add_attribute_step4\":{}}".as_bytes().to_vec()), + contract_addr: env.contract.address.into_string(), + code_hash: env.contract.code_hash, + funds: vec![], + })) + .add_attribute_plaintext("attr3", "🦄") + .set_data(to_binary("step3")?)), + ExecuteMsg::AddAttributeStep4 {} => Ok(Response::new() + .add_attribute_plaintext("attr4", "🦄") + .set_data(to_binary("step4")?)), + ExecuteMsg::InitV10NoReply { + counter, + code_id, + code_hash, + } => { + let mut resp = Response::default(); + + let msg = + "{\"init_from_v1\":{\"counter\":".to_string() + counter.to_string().as_str() + "}}"; + resp.messages.push(SubMsg { + id: 8888, + msg: CosmosMsg::Wasm(WasmMsg::Instantiate { + code_hash, + msg: Binary::from(msg.as_bytes().to_vec()), + funds: vec![], + label: "new2231231".to_string(), + code_id, + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Never, + }); + + Ok(resp) + } + ExecuteMsg::ExecV10NoReply { address, code_hash } => { + let mut resp = Response::default(); + + resp.messages.push(SubMsg { + id: 8889, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + msg: Binary::from("{\"execute_from_v1\":{\"counter\":20}}".as_bytes().to_vec()), + contract_addr: address, + code_hash, + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Never, + }); + + Ok(resp) + } + ExecuteMsg::QueryV10 { address, code_hash } => { + let response = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { + code_hash, + contract_addr: address, + msg: to_binary(&ExternalMessages::GetCountFromV1 {})?, + }))?; + + match response { + QueryRes::Get { count } => { + let mut resp = Response::default(); + resp.data = Some((count as u32).to_be_bytes().into()); + return Ok(resp); + } + } + } + + ExecuteMsg::InitV10WithError { code_id, code_hash } => { + let mut resp = Response::default(); + + let msg = "{\"init_from_v1_with_error\":{}"; + resp.messages.push(SubMsg { + id: 2000, + msg: CosmosMsg::Wasm(WasmMsg::Instantiate { + code_hash, + msg: Binary::from(msg.as_bytes().to_vec()), + funds: vec![], + label: "new2231231".to_string(), + code_id, + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Always, + }); + + Ok(resp) + } + ExecuteMsg::ExecV10WithError { address, code_hash } => { + let mut resp = Response::default(); + + resp.messages.push(SubMsg { + id: 2100, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + msg: Binary::from("{\"execute_from_v1_with_error\":{}}".as_bytes().to_vec()), + contract_addr: address, + code_hash, + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Always, + }); + + Ok(resp) + } + ExecuteMsg::InitV10NoReplyWithError { code_id, code_hash } => { + let mut resp = Response::default(); + + let msg = "{\"init_from_v1_with_error\":{}}"; + resp.messages.push(SubMsg { + id: 8890, + msg: CosmosMsg::Wasm(WasmMsg::Instantiate { + code_hash, + msg: Binary::from(msg.as_bytes().to_vec()), + funds: vec![], + label: "new2231231".to_string(), + code_id, + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Never, + }); + + Ok(resp) + } + ExecuteMsg::ExecV10NoReplyWithError { address, code_hash } => { + let mut resp = Response::default(); + + resp.messages.push(SubMsg { + id: 8891, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + msg: Binary::from("{\"execute_from_v1_with_error\":{}}".as_bytes().to_vec()), + contract_addr: address, + code_hash, + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Never, + }); + + Ok(resp) + } + ExecuteMsg::QueryV10WithError { address, code_hash } => { + deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { + code_hash, + contract_addr: address, + msg: to_binary(&ExternalMessages::QueryFromV1WithError {})?, + }))?; + + // shouldn't be reachable + Ok(Response::default()) + } + // These were ported from the v0.10 test-contract: + ExecuteMsg::A { + contract_addr, + code_hash, + x, + y, + } => Ok(a(deps, env, contract_addr, code_hash, x, y)), + ExecuteMsg::B { + contract_addr, + code_hash, + x, + y, + } => Ok(b(deps, env, contract_addr, code_hash, x, y)), + ExecuteMsg::C { x, y } => Ok(c(deps, env, x, y)), + ExecuteMsg::UnicodeData {} => Ok(unicode_data(deps, env)), + ExecuteMsg::EmptyLogKeyValue {} => Ok(empty_log_key_value(deps, env)), + ExecuteMsg::EmptyData {} => Ok(empty_data(deps, env)), + ExecuteMsg::NoData {} => Ok(no_data(deps, env)), + ExecuteMsg::ContractError { error_type } => Err(map_string_to_error(error_type)), + ExecuteMsg::NoLogs {} => Ok(Response::default()), + ExecuteMsg::CallbackToInit { code_id, code_hash } => { + Ok(exec_callback_to_init(deps, env, code_id, code_hash)) + } + ExecuteMsg::CallbackBadParams { + contract_addr, + code_hash, + } => Ok(exec_callback_bad_params(contract_addr, code_hash)), + ExecuteMsg::CallbackContractError { + contract_addr, + code_hash, + } => Ok(exec_with_callback_contract_error(contract_addr, code_hash)), + ExecuteMsg::SetState { key, value } => Ok(set_state(deps, key, value)), + ExecuteMsg::GetState { key } => Ok(get_state(deps, key)), + ExecuteMsg::RemoveState { key } => Ok(remove_state(deps, key)), + ExecuteMsg::TestCanonicalizeAddressErrors {} => test_canonicalize_address_errors(deps), + ExecuteMsg::Panic {} => panic!("panic in exec"), + ExecuteMsg::AllocateOnHeap { bytes } => Ok(allocate_on_heap(bytes as usize)), + ExecuteMsg::PassNullPointerToImportsShouldThrow { pass_type } => { + Ok(pass_null_pointer_to_imports_should_throw(deps, pass_type)) + } + ExecuteMsg::SendExternalQuery { to, code_hash } => { + Ok(Response::new().set_data(vec![send_external_query(deps.as_ref(), to, code_hash)])) + } + ExecuteMsg::SendExternalQueryDepthCounter { + to, + code_hash, + depth, + } => Ok( + Response::new().set_data(vec![send_external_query_depth_counter( + deps.as_ref(), + to, + depth, + code_hash, + )]), + ), + ExecuteMsg::SendExternalQueryRecursionLimit { + to, + code_hash, + depth, + } => Ok( + Response::new().set_data(to_binary(&send_external_query_recursion_limit( + deps.as_ref(), + to, + depth, + code_hash, + )?)?), + ), + ExecuteMsg::SendExternalQueryPanic { to, code_hash } => { + send_external_query_panic(deps, to, code_hash) + } + ExecuteMsg::SendExternalQueryError { to, code_hash } => { + send_external_query_stderror(deps, to, code_hash) + } + ExecuteMsg::SendExternalQueryBadAbi { to, code_hash } => { + send_external_query_bad_abi(deps, to, code_hash) + } + ExecuteMsg::SendExternalQueryBadAbiReceiver { to, code_hash } => { + send_external_query_bad_abi_receiver(deps, to, code_hash) + } + ExecuteMsg::LogMsgSender {} => { + Ok(Response::new().add_attribute("msg.sender", info.sender.as_str())) + } + ExecuteMsg::CallbackToLogMsgSender { to, code_hash } => Ok(Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: to.clone(), + code_hash, + msg: Binary::from(r#"{"log_msg_sender":{}}"#.as_bytes().to_vec()), + funds: vec![], + })) + .add_attribute("hi", "hey")), + ExecuteMsg::DepositToContract {} => { + Ok(Response::new().set_data(to_binary(&info.funds).unwrap())) + } + ExecuteMsg::SendFunds { + amount, + from: _, + to, + denom, + } => Ok(Response::new().add_message(CosmosMsg::Bank(BankMsg::Send { + to_address: to, + amount: coins(amount.into(), denom), + }))), + ExecuteMsg::SendFundsToInitCallback { + amount, + denom, + code_id, + code_hash, + } => Ok( + Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Instantiate { + msg: Binary("{\"nop\":{}}".as_bytes().to_vec()), + code_id, + code_hash, + label: String::from("yo"), + funds: coins(amount.into(), denom), + })), + ), + ExecuteMsg::SendFundsToExecCallback { + amount, + denom, + to, + code_hash, + } => Ok( + Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Execute { + msg: Binary("{\"no_data\":{}}".as_bytes().to_vec()), + contract_addr: to, + code_hash, + funds: coins(amount.into(), denom), + })), + ), + ExecuteMsg::Sleep { ms } => { + thread::sleep(time::Duration::from_millis(ms)); + + Ok(Response::new()) + } + ExecuteMsg::WithFloats { x, y } => Ok(Response::new().set_data(use_floats(x, y))), + ExecuteMsg::CallToInit { + code_id, + code_hash, + label, + msg, + } => Ok(Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Instantiate { + code_id, + code_hash, + msg: Binary(msg.as_bytes().into()), + funds: vec![], + label, + })) + .add_attribute("a", "a")), + ExecuteMsg::CallToExec { + addr, + code_hash, + msg, + } => Ok(Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: addr, + code_hash, + msg: Binary(msg.as_bytes().into()), + funds: vec![], + })) + .add_attribute("b", "b")), + ExecuteMsg::CallToQuery { + addr, + code_hash, + msg, + } => { + let answer: u32 = deps + .querier + .query(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr: addr, + code_hash, + msg: Binary::from(msg.as_bytes().to_vec()), + })) + .map_err(|err| { + StdError::generic_err(format!("Got an error from query: {:?}", err)) + })?; + + Ok(Response::new().add_attribute("c", format!("{}", answer))) + } + ExecuteMsg::StoreReallyLongKey {} => { + let mut store = PrefixedStorage::new(deps.storage, b"my_prefix"); + store.set(REALLY_LONG, b"hello"); + Ok(Response::default()) + } + ExecuteMsg::StoreReallyShortKey {} => { + let mut store = PrefixedStorage::new(deps.storage, b"my_prefix"); + store.set(b"a", b"hello"); + Ok(Response::default()) + } + ExecuteMsg::StoreReallyLongValue {} => { + let mut store = PrefixedStorage::new(deps.storage, b"my_prefix"); + store.set(b"hello", REALLY_LONG); + Ok(Response::default()) + } + ExecuteMsg::Secp256k1Verify { + pubkey, + sig, + msg_hash, + iterations, + } => { + let mut res = Ok(Response::new()); + + // loop for benchmarking + for _ in 0..iterations { + res = match deps.api.secp256k1_verify( + msg_hash.as_slice(), + sig.as_slice(), + pubkey.as_slice(), + ) { + Ok(result) => { + Ok(Response::new().add_attribute("result", format!("{}", result))) + } + Err(err) => Err(StdError::generic_err(format!("{:?}", err))), + }; + } + + return res; + } + ExecuteMsg::Secp256k1VerifyFromCrate { + pubkey, + sig, + msg_hash, + iterations, + } => { + let mut res = Ok(Response::new()); + + // loop for benchmarking + for _ in 0..iterations { + let secp256k1_verifier = Secp256k1::verification_only(); + + let secp256k1_signature = + secp256k1::Signature::from_compact(&sig.0).map_err(|err| { + StdError::generic_err(format!("Malformed signature: {:?}", err)) + })?; + let secp256k1_pubkey = secp256k1::PublicKey::from_slice(pubkey.0.as_slice()) + .map_err(|err| StdError::generic_err(format!("Malformed pubkey: {:?}", err)))?; + let secp256k1_msg = + secp256k1::Message::from_slice(&msg_hash.as_slice()).map_err(|err| { + StdError::generic_err(format!( + "Failed to create a secp256k1 message from signed_bytes: {:?}", + err + )) + })?; + + res = match secp256k1_verifier.verify( + &secp256k1_msg, + &secp256k1_signature, + &secp256k1_pubkey, + ) { + Ok(()) => Ok(Response::new().add_attribute("result", "true")), + Err(_err) => Ok(Response::new().add_attribute("result", "false")), + }; + } + + return res; + } + ExecuteMsg::Ed25519Verify { + pubkey, + sig, + msg, + iterations, + } => { + let mut res = Ok(Response::new()); + + // loop for benchmarking + for _ in 0..iterations { + res = + match deps + .api + .ed25519_verify(msg.as_slice(), sig.as_slice(), pubkey.as_slice()) + { + Ok(result) => { + Ok(Response::new().add_attribute("result", format!("{}", result))) + } + Err(err) => Err(StdError::generic_err(format!("{:?}", err))), + }; + } + + return res; + } + ExecuteMsg::Ed25519BatchVerify { + pubkeys, + sigs, + msgs, + iterations, + } => { + let mut res = Ok(Response::new()); + + // loop for benchmarking + for _ in 0..iterations { + res = match deps.api.ed25519_batch_verify( + msgs.iter() + .map(|m| m.as_slice()) + .collect::>() + .as_slice(), + sigs.iter() + .map(|s| s.as_slice()) + .collect::>() + .as_slice(), + pubkeys + .iter() + .map(|p| p.as_slice()) + .collect::>() + .as_slice(), + ) { + Ok(result) => { + Ok(Response::new().add_attribute("result", format!("{}", result))) + } + Err(err) => Err(StdError::generic_err(format!("{:?}", err))), + }; + } + + return res; + } + ExecuteMsg::Secp256k1RecoverPubkey { + msg_hash, + sig, + recovery_param, + iterations, + } => { + let mut res = Ok(Response::new()); + + // loop for benchmarking + for _ in 0..iterations { + res = match deps.api.secp256k1_recover_pubkey( + msg_hash.as_slice(), + sig.as_slice(), + recovery_param, + ) { + Ok(result) => Ok(Response::new() + .add_attribute("result", format!("{}", Binary(result).to_base64()))), + Err(err) => Err(StdError::generic_err(format!("{:?}", err))), + }; + } + + return res; + } + ExecuteMsg::Secp256k1Sign { + msg, + privkey, + iterations, + } => { + let mut res = Ok(Response::new()); + + // loop for benchmarking + for _ in 0..iterations { + res = match deps.api.secp256k1_sign(msg.as_slice(), privkey.as_slice()) { + Ok(result) => Ok(Response::new() + .add_attribute("result", format!("{}", Binary(result).to_base64()))), + Err(err) => Err(StdError::generic_err(format!("{:?}", err))), + }; + } + + return res; + } + ExecuteMsg::Ed25519Sign { + msg, + privkey, + iterations, + } => { + let mut res = Ok(Response::new()); + + // loop for benchmarking + for _ in 0..iterations { + res = match deps.api.ed25519_sign(msg.as_slice(), privkey.as_slice()) { + Ok(result) => Ok(Response::new() + .add_attribute("result", format!("{}", Binary(result).to_base64()))), + Err(err) => Err(StdError::generic_err(format!("{:?}", err))), + }; + } + + return res; + } + ExecuteMsg::BankMsgSend { to, amount } => { + Ok(Response::new().add_message(CosmosMsg::Bank(BankMsg::Send { + to_address: to, + amount, + }))) + } + ExecuteMsg::BankMsgBurn { amount } => { + Ok(Response::new().add_message(CosmosMsg::Bank(BankMsg::Burn { amount }))) + } + ExecuteMsg::CosmosMsgCustom {} => { + Ok(Response::new().add_message(CosmosMsg::Custom(Empty {}))) + } + ExecuteMsg::SendMultipleFundsToInitCallback { + coins, + code_id, + code_hash, + } => Ok( + Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Instantiate { + code_id, + code_hash, + msg: Binary("{\"nop\":{}}".as_bytes().to_vec()), + funds: coins, + label: "test".to_string(), + })), + ), + ExecuteMsg::SendMultipleFundsToExecCallback { + coins, + to, + code_hash, + } => Ok( + Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: to, + code_hash, + msg: Binary("{\"no_data\":{}}".as_bytes().to_vec()), + funds: coins, + })), + ), + ExecuteMsg::ValidateAddress { addr } => match deps.api.addr_validate(addr.as_str()) { + Ok(a) => Ok(Response::new().set_data(a.as_bytes())), + Err(_) => Ok(Response::new().set_data(to_binary("Apple")?)), + }, + ExecuteMsg::GetEnv {} => Ok(Response::new() + .add_attribute("env", serde_json_wasm::to_string(&env).unwrap()) + .add_attribute("info", serde_json_wasm::to_string(&info).unwrap())), + ExecuteMsg::ExecuteMultipleContracts { details } => { + if details.len() == 0 { + return Ok(Response::default().set_data(env.contract.address.as_bytes())); + } + + if details[0].should_error { + return Err(StdError::generic_err("Error by request")); + } + + Ok(Response::new() + .add_submessage(SubMsg { + id: details[0].msg_id, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: details[0].contract_hash.clone(), + contract_addr: details[0].contract_address.clone(), + msg: Binary( + format!( + r#"{{"execute_multiple_contracts":{{"details":{}}}}}"#, + serde_json_wasm::to_string(&details[1..].to_vec()).unwrap(), + ) + .into_bytes(), + ), + funds: vec![], + }) + .into(), + reply_on: match details[0].msg_id { + 0 => ReplyOn::Never, + _ => ReplyOn::Always, + }, + gas_limit: None, + }) + .set_data(details[0].data.as_bytes())) + } + ExecuteMsg::IBCLifecycleComplete(IBCLifecycleComplete::IBCAck { + channel, + sequence, + ack, + success, + }) => Ok(Response::default().add_attributes(vec![ + ("ibc_lifecycle_complete.ibc_ack.channel", channel), + ( + "ibc_lifecycle_complete.ibc_ack.sequence", + sequence.to_string(), + ), + ("ibc_lifecycle_complete.ibc_ack.ack", ack), + ( + "ibc_lifecycle_complete.ibc_ack.success", + success.to_string(), + ), + ])), + ExecuteMsg::IBCLifecycleComplete(IBCLifecycleComplete::IBCTimeout { + channel, + sequence, + }) => Ok(Response::default().add_attributes(vec![ + ("ibc_lifecycle_complete.ibc_timeout.channel", channel), + ( + "ibc_lifecycle_complete.ibc_timeout.sequence", + sequence.to_string(), + ), + ])), + } +} + +pub fn increment(env: Env, deps: DepsMut, c: u64) -> StdResult { + if c == 0 { + return Err(StdError::generic_err("got wrong counter on increment")); + } + + if c == 9875 { + let new_count = count_read(deps.storage).load()? + 100; + count(deps.storage).save(&new_count)?; + return Err(StdError::generic_err("got wrong counter on increment")); + } + + if c == 9876 { + let new_count = count_read(deps.storage).load()? + 100; + count(deps.storage).save(&new_count)?; + panic!() + } + + if c == 9911 { + let mut resp = Response::default(); + resp.messages.push(SubMsg { + id: 1304, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address.into_string(), + code_hash: env.contract.code_hash, + msg: Binary::from("{\"increment\":{\"addition\":5}}".as_bytes().to_vec()), + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Always, + }); + + return Ok(resp); + } + + let new_count = count_read(deps.storage).load()? + c; + count(deps.storage).save(&new_count)?; + + let mut resp = Response::default(); + resp.data = Some((new_count as u32).to_be_bytes().into()); + + Ok(resp) +} + +pub fn transfer_money(_deps: DepsMut, amount: u64) -> StdResult { + let mut resp = Response::default(); + resp.messages.push(SubMsg { + id: 1337, + msg: CosmosMsg::Bank(BankMsg::Send { + to_address: "secret105w4vl4gm7q00yg5jngewt5kp7aj0xjk7zrnhw".to_string(), + amount: coins(amount as u128, "uscrt"), + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Always, + }); + + Ok(resp) +} + +pub fn recursive_reply(env: Env, _deps: DepsMut) -> StdResult { + let mut resp = Response::default(); + resp.messages.push(SubMsg { + id: 1304, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address.into_string(), + code_hash: env.contract.code_hash, + msg: Binary::from("{\"increment\":{\"addition\":2}}".as_bytes().to_vec()), + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Always, + }); + + Ok(resp) +} + +pub fn sub_msg_loop(env: Env, _deps: DepsMut, iter: u64) -> StdResult { + if iter == 0 { + return Err(StdError::generic_err("stopped loop")); + } + + let mut resp = Response::default(); + let msg = "{\"sub_msg_loop_iner\":{\"iter\":".to_string() + iter.to_string().as_str() + "}}"; + resp.messages.push(SubMsg { + id: 1500, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address.into_string(), + code_hash: env.contract.code_hash, + msg: cosmwasm_std::Binary(msg.as_bytes().to_vec()), + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Always, + }); + + Ok(resp) +} + +pub fn sub_msg_loop_iner(_env: Env, deps: DepsMut, iter: u64) -> StdResult { + if iter == 0 { + return Err(StdError::generic_err("stopped loop")); + } + + increment(_env, deps, 1)?; + + let mut resp = Response::default(); + resp.data = Some(((iter - 1) as u64).to_string().as_bytes().into()); + + Ok(resp) +} + +pub fn send_multiple_sub_messages(env: Env, _deps: DepsMut) -> StdResult { + let mut resp = Response::default(); + resp.messages.push(SubMsg { + id: 1600, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address.clone().into_string(), + code_hash: env.contract.code_hash.clone(), + msg: Binary::from("{\"increment\":{\"addition\":2}}".as_bytes().to_vec()), + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Never, + }); + + resp.messages.push(SubMsg { + id: 1601, + msg: CosmosMsg::Wasm(WasmMsg::Instantiate { + code_hash: env.contract.code_hash.clone(), + msg: Binary::from( + "{\"counter\":{\"counter\":150, \"expires\":100}}" + .as_bytes() + .to_vec(), + ), + funds: vec![], + label: "new202213".to_string(), + code_id: 1, + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Always, + }); + + resp.messages.push(SubMsg { + id: 1602, + msg: CosmosMsg::Bank(BankMsg::Send { + to_address: "secret105w4vl4gm7q00yg5jngewt5kp7aj0xjk7zrnhw".to_string(), + amount: coins(1200 as u128, "uscrt"), + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Always, + }); + + resp.messages.push(SubMsg { + id: 1603, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address.into_string(), + code_hash: env.contract.code_hash.clone(), + msg: Binary::from("{\"increment\":{\"addition\":2}}".as_bytes().to_vec()), + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Never, + }); + + Ok(resp) +} + +pub fn send_multiple_sub_messages_no_reply(env: Env, deps: DepsMut) -> StdResult { + let mut resp = Response::default(); + + resp.messages.push(SubMsg { + id: 1610, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address.clone().into_string(), + code_hash: env.contract.code_hash.clone(), + msg: Binary::from("{\"increment\":{\"addition\":2}}".as_bytes().to_vec()), + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Never, + }); + + resp.messages.push(SubMsg { + id: 1611, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address.clone().into_string(), + code_hash: env.contract.code_hash.clone(), + msg: Binary::from("{\"increment\":{\"addition\":2}}".as_bytes().to_vec()), + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Never, + }); + + resp.messages.push(SubMsg { + id: 1612, + msg: CosmosMsg::Wasm(WasmMsg::Instantiate { + code_hash: env.contract.code_hash.clone(), + msg: Binary::from( + "{\"counter\":{\"counter\":150, \"expires\":100}}" + .as_bytes() + .to_vec(), + ), + funds: vec![], + label: "new202213".to_string(), + code_id: 1, + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Never, + }); + + resp.messages.push(SubMsg { + id: 1613, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address.clone().into_string(), + code_hash: env.contract.code_hash.clone(), + msg: Binary::from("{\"increment\":{\"addition\":2}}".as_bytes().to_vec()), + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Never, + }); + + resp.data = Some( + (count_read(deps.storage).load()? as u32) + .to_be_bytes() + .into(), + ); + Ok(resp) +} + +pub fn send_multiple_sub_messages_no_reply_with_error( + env: Env, + deps: DepsMut, +) -> StdResult { + let mut resp = Response::default(); + + resp.messages.push(SubMsg { + id: 1610, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address.clone().into_string(), + code_hash: env.contract.code_hash.clone(), + msg: Binary::from("{\"increment\":{\"addition\":2}}".as_bytes().to_vec()), + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Error, + }); + + resp.messages.push(SubMsg { + id: 1611, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address.clone().into_string(), + code_hash: env.contract.code_hash.clone(), + msg: Binary::from("{\"increment\":{\"addition\":9875}}".as_bytes().to_vec()), + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Success, + }); + + resp.messages.push(SubMsg { + id: 1613, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address.clone().into_string(), + code_hash: env.contract.code_hash.clone(), + msg: Binary::from("{\"increment\":{\"addition\":2}}".as_bytes().to_vec()), + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Never, + }); + + let new_count = count_read(deps.storage).load()? + 5; + count(deps.storage).save(&new_count)?; + + resp.data = Some( + (count_read(deps.storage).load()? as u32) + .to_be_bytes() + .into(), + ); + Ok(resp) +} + +pub fn send_multiple_sub_messages_with_reply_with_error( + env: Env, + deps: DepsMut, +) -> StdResult { + let mut resp = Response::default(); + + resp.messages.push(SubMsg { + id: 3000, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address.clone().into_string(), + code_hash: env.contract.code_hash.clone(), + msg: Binary::from("{\"increment\":{\"addition\":2}}".as_bytes().to_vec()), + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Always, + }); + + resp.messages.push(SubMsg { + id: 3001, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address.clone().into_string(), + code_hash: env.contract.code_hash.clone(), + msg: Binary::from("{\"increment\":{\"addition\":9875}}".as_bytes().to_vec()), + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Error, + }); + + resp.messages.push(SubMsg { + id: 3003, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address.clone().into_string(), + code_hash: env.contract.code_hash.clone(), + msg: Binary::from("{\"increment\":{\"addition\":2}}".as_bytes().to_vec()), + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Never, + }); + + resp.messages.push(SubMsg { + id: 3001, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address.clone().into_string(), + code_hash: env.contract.code_hash.clone(), + msg: Binary::from("{\"increment\":{\"addition\":9875}}".as_bytes().to_vec()), + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Always, + }); + + let new_count = count_read(deps.storage).load()? + 5; + count(deps.storage).save(&new_count)?; + + resp.data = Some( + (count_read(deps.storage).load()? as u32) + .to_be_bytes() + .into(), + ); + Ok(resp) +} + +pub fn send_multiple_sub_messages_with_reply_with_panic( + env: Env, + deps: DepsMut, +) -> StdResult { + let mut resp = Response::default(); + + resp.messages.push(SubMsg { + id: 3000, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address.clone().into_string(), + code_hash: env.contract.code_hash.clone(), + msg: Binary::from("{\"increment\":{\"addition\":2}}".as_bytes().to_vec()), + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Always, + }); + + resp.messages.push(SubMsg { + id: 3001, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address.clone().into_string(), + code_hash: env.contract.code_hash.clone(), + msg: Binary::from("{\"increment\":{\"addition\":9876}}".as_bytes().to_vec()), + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Always, + }); + + resp.messages.push(SubMsg { + id: 3001, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address.clone().into_string(), + code_hash: env.contract.code_hash.clone(), + msg: Binary::from("{\"increment\":{\"addition\":9876}}".as_bytes().to_vec()), + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Error, + }); + let new_count = count_read(deps.storage).load()? + 5; + count(deps.storage).save(&new_count)?; + + resp.data = Some( + (count_read(deps.storage).load()? as u32) + .to_be_bytes() + .into(), + ); + Ok(resp) +} + +pub fn send_multiple_sub_messages_no_reply_with_panic( + env: Env, + deps: DepsMut, +) -> StdResult { + let mut resp = Response::default(); + + resp.messages.push(SubMsg { + id: 1610, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address.clone().into_string(), + code_hash: env.contract.code_hash.clone(), + msg: Binary::from("{\"increment\":{\"addition\":2}}".as_bytes().to_vec()), + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Never, + }); + + resp.messages.push(SubMsg { + id: 1611, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address.clone().into_string(), + code_hash: env.contract.code_hash.clone(), + msg: Binary::from("{\"increment\":{\"addition\":9876}}".as_bytes().to_vec()), + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Never, + }); + + resp.messages.push(SubMsg { + id: 1613, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address.clone().into_string(), + code_hash: env.contract.code_hash.clone(), + msg: Binary::from("{\"increment\":{\"addition\":2}}".as_bytes().to_vec()), + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Never, + }); + + let new_count = count_read(deps.storage).load()? + 5; + count(deps.storage).save(&new_count)?; + + resp.data = Some( + (count_read(deps.storage).load()? as u32) + .to_be_bytes() + .into(), + ); + Ok(resp) +} + +pub fn recursive_reply_fail(env: Env, _deps: DepsMut) -> StdResult { + let mut resp = Response::default(); + resp.messages.push(SubMsg { + id: 1305, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address.into_string(), + code_hash: env.contract.code_hash, + msg: Binary::from("{\"increment\":{\"addition\":0}}".as_bytes().to_vec()), + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Always, + }); + + Ok(resp) +} + +pub fn init_new_contract(env: Env, _deps: DepsMut) -> StdResult { + let mut resp = Response::default(); + resp.messages.push(SubMsg { + id: 1404, + msg: CosmosMsg::Wasm(WasmMsg::Instantiate { + code_hash: env.contract.code_hash, + msg: Binary::from( + "{\"counter\":{\"counter\":150, \"expires\":100}}" + .as_bytes() + .to_vec(), + ), + funds: vec![], + label: "new202213".to_string(), + code_id: 1, + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Always, + }); + + Ok(resp) +} + +pub fn init_new_contract_with_error(env: Env, _deps: DepsMut) -> StdResult { + let mut resp = Response::default(); + resp.messages.push(SubMsg { + id: 1405, + msg: CosmosMsg::Wasm(WasmMsg::Instantiate { + code_hash: env.contract.code_hash, + msg: Binary::from( + "{\"counter\":{\"counter\":0, \"expires\":100}}" + .as_bytes() + .to_vec(), + ), + funds: vec![], + label: "new2022133".to_string(), + code_id: 1, + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Always, + }); + + Ok(resp) +} + +#[entry_point] +pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { + match msg { + QueryMsg::Get {} => to_binary(&get(deps, env)?), + + // These were ported from the v0.10 test-contract: + QueryMsg::ContractError { error_type } => Err(map_string_to_error(error_type)), + QueryMsg::Panic {} => panic!("panic in query"), + QueryMsg::ReceiveExternalQuery { num } | QueryMsg::ReceiveExternalQueryV1 { num } => { + Ok(Binary(serde_json_wasm::to_vec(&(num + 1)).unwrap())) + } + QueryMsg::SendExternalQueryInfiniteLoop { to, code_hash } => { + send_external_query_infinite_loop(deps, to, code_hash) + } + QueryMsg::WriteToStorage {} => write_to_storage_in_query(deps.storage), + QueryMsg::RemoveFromStorage {} => remove_from_storage_in_query(deps.storage), + QueryMsg::SendExternalQueryDepthCounter { + to, + depth, + code_hash, + } => Ok(to_binary(&send_external_query_depth_counter( + deps, to, depth, code_hash, + )) + .unwrap()), + QueryMsg::SendExternalQueryRecursionLimit { + to, + depth, + code_hash, + } => to_binary(&send_external_query_recursion_limit( + deps, to, depth, code_hash, + )?), + QueryMsg::CallToQuery { + addr, + code_hash, + msg, + } => { + let answer: u32 = deps + .querier + .query(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr: addr, + code_hash, + msg: Binary::from(msg.as_bytes().to_vec()), + })) + .map_err(|err| { + StdError::generic_err(format!("Got an error from query: {:?}", err)) + })?; + return Ok(to_binary(&answer)?); + } + QueryMsg::GetContractVersion {} => { + let answer: u8 = 1; + return Ok(to_binary(&answer)?); + } + QueryMsg::GetEnv {} => Ok(Binary::from( + serde_json_wasm::to_string(&env) + .unwrap() + .as_bytes() + .to_vec(), + )), + } +} + +#[entry_point] +pub fn reply(deps: DepsMut, env: Env, reply: Reply) -> StdResult { + match (reply.id, reply.result) { + (1337, SubMsgResult::Err(_)) => { + let mut resp = Response::default(); + resp.data = Some( + (count_read(deps.storage).load()? as u32) + .to_be_bytes() + .into(), + ); + + Ok(resp) + } + (1337, SubMsgResult::Ok(_)) => Err(StdError::generic_err("got wrong bank answer")), + + (1304, SubMsgResult::Err(e)) => Err(StdError::generic_err(format!( + "recursive reply failed: {}", + e + ))), + (1304, SubMsgResult::Ok(_)) => { + let mut resp = Response::default(); + resp.data = Some( + (count_read(deps.storage).load()? as u32) + .to_be_bytes() + .into(), + ); + + Ok(resp) + } + (1305, SubMsgResult::Ok(_)) => { + Err(StdError::generic_err(format!("recursive reply failed"))) + } + (1305, SubMsgResult::Err(_)) => { + let mut resp = Response::default(); + let new_count = 10; + count(deps.storage).save(&new_count)?; + + resp.data = Some( + (count_read(deps.storage).load()? as u32) + .to_be_bytes() + .into(), + ); + + Ok(resp) + } + + (1404, SubMsgResult::Err(e)) => Err(StdError::generic_err(format!( + "recursive init failed: {}", + e + ))), + (1404, SubMsgResult::Ok(s)) => match s.data { + Some(x) => { + let response = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { + code_hash: env.contract.code_hash, + contract_addr: String::from_utf8(x.to_vec())?, + msg: to_binary(&QueryMsg::Get {})?, + }))?; + + match response { + QueryRes::Get { count } => { + let mut resp = Response::default(); + resp.data = Some((count as u32).to_be_bytes().into()); + return Ok(resp); + } + } + } + None => Err(StdError::generic_err(format!( + "Init didn't response with contract address", + ))), + }, + (1405, SubMsgResult::Ok(_)) => Err(StdError::generic_err(format!( + "recursive init with error failed" + ))), + (1405, SubMsgResult::Err(_)) => { + let mut resp = Response::default(); + let new_count = 1337; + count(deps.storage).save(&new_count)?; + + resp.data = Some( + (count_read(deps.storage).load()? as u32) + .to_be_bytes() + .into(), + ); + + Ok(resp) + } + + (1500, SubMsgResult::Ok(iter)) => match iter.data { + Some(x) => { + let it = String::from_utf8(x.to_vec())?; + let mut resp = Response::default(); + + let msg = "{\"sub_msg_loop_iner\":{\"iter\":".to_string() + it.as_str() + "}}"; + resp.messages.push(SubMsg { + id: 1500, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address.into_string(), + code_hash: env.contract.code_hash, + msg: Binary::from(msg.as_bytes().to_vec()), + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Always, + }); + + Ok(resp) + } + None => Err(StdError::generic_err(format!( + "Init didn't response with contract address", + ))), + }, + (1500, SubMsgResult::Err(_)) => { + let mut resp = Response::default(); + resp.data = Some( + (count_read(deps.storage).load()? as u32) + .to_be_bytes() + .into(), + ); + + Ok(resp) + } + + (1601, SubMsgResult::Err(e)) => Err(StdError::generic_err(format!( + "recursive init failed: {}", + e + ))), + (1601, SubMsgResult::Ok(s)) => match s.data { + Some(_) => { + let mut resp = Response::default(); + let new_count = 101; + count(deps.storage).save(&new_count)?; + + resp.data = Some( + (count_read(deps.storage).load()? as u32) + .to_be_bytes() + .into(), + ); + + Ok(resp) + } + None => Err(StdError::generic_err(format!( + "Init didn't response with contract address", + ))), + }, + (1602, SubMsgResult::Err(_)) => { + let mut resp = Response::default(); + let new_count = 102; + count(deps.storage).save(&new_count)?; + + resp.data = Some( + (count_read(deps.storage).load()? as u32) + .to_be_bytes() + .into(), + ); + + Ok(resp) + } + (1602, SubMsgResult::Ok(_)) => Err(StdError::generic_err("got wrong bank answer")), + (1700, SubMsgResult::Ok(s)) => { + if s.events.len() == 0 { + return Err(StdError::generic_err(format!( + "Init didn't response with contract address", + ))); + } + + if s.events[0].attributes.len() == 0 { + return Err(StdError::generic_err(format!( + "Init didn't response with contract address", + ))); + } + + if s.events[0].attributes[0].key != "contract_address" { + return Err(StdError::generic_err(format!( + "Init didn't response with contract address, key was {:?}", + s.events[0].attributes[0].key, + ))); + } + + let mut resp = Response::default(); + resp.data = Some(s.events[0].attributes[0].value.as_bytes().into()); + + Ok(resp) + } + (1700, SubMsgResult::Err(_)) => Err(StdError::generic_err("Failed to init v010 contract")), + (1800, SubMsgResult::Ok(s)) => match s.data { + Some(x) => { + let counter = String::from_utf8(x.to_vec())?; + let mut resp = Response::default(); + resp.data = Some(counter.as_bytes().into()); + + Ok(resp) + } + None => Err(StdError::generic_err(format!( + "Init didn't response with contract address", + ))), + }, + (1800, SubMsgResult::Err(_)) => { + Err(StdError::generic_err("Failed to execute v010 contract")) + } + + (2000, SubMsgResult::Ok(_)) => Err(StdError::generic_err(format!( + "Init with error didn't response with error", + ))), + (2000, SubMsgResult::Err(_)) => Ok(Response::default()), + (2100, SubMsgResult::Ok(_)) => Err(StdError::generic_err(format!( + "Execute with error didn't response with error", + ))), + (2100, SubMsgResult::Err(_)) => Ok(Response::default()), + (2200, SubMsgResult::Ok(_)) => Ok(Response::new() + .add_attribute("attr5", "🤯") + .add_attribute("attr6", "🦄")), + (2200, SubMsgResult::Err(_)) => { + Err(StdError::generic_err(format!("Add attributes failed",))) + } + (2300, SubMsgResult::Ok(_)) => Ok(Response::new() + .add_attribute_plaintext("attr5", "🤯") + .add_attribute_plaintext("attr6", "🦄")), + (2300, SubMsgResult::Err(_)) => { + Err(StdError::generic_err(format!("Add attributes failed",))) + } + (2400, SubMsgResult::Ok(_)) => Ok(Response::new() + .add_event( + Event::new("cyber5".to_string()) + .add_attribute("attr1", "😗") + .add_attribute("attr2", "😋"), + ) + .add_event( + Event::new("cyber6".to_string()) + .add_attribute("attr3", "😉") + .add_attribute("attr4", "😊"), + )), + (2400, SubMsgResult::Err(_)) => Err(StdError::generic_err(format!("Add events failed",))), + (2500, SubMsgResult::Ok(_)) => Ok(Response::new() + .add_event( + Event::new("cyber3".to_string()) + .add_attribute("attr9", "🤯") + .add_attribute("attr10", "🤟"), + ) + .add_attribute("attr11", "😉") + .add_attribute_plaintext("attr12", "😊")), + (2500, SubMsgResult::Err(_)) => { + Err(StdError::generic_err(format!("Add mixed events failed",))) + } + (2600, SubMsgResult::Ok(_)) => { + // busy work + let mut v = vec![0; 65536]; + let mut x = 0; + loop { + x += (x + 1) % 65536; + v[x] = 65536 - x; + } + } + (2600, SubMsgResult::Err(_)) => { + Err(StdError::generic_err(format!("Gas submessage failed",))) + } + (3000, SubMsgResult::Ok(_)) => { + let new_count = count_read(deps.storage).load()? + 3; + count(deps.storage).save(&new_count)?; + Ok(Response::default()) + } + (3000, SubMsgResult::Err(_)) => { + Err(StdError::generic_err(format!("Revert submessage failed",))) + } + (3001, SubMsgResult::Ok(_)) => Err(StdError::generic_err(format!( + "Revert submessage should fail", + ))), + (3001, SubMsgResult::Err(_)) => Ok(Response::default()), + (8000, SubMsgResult::Ok(_)) => Err(StdError::generic_err(format!("Unreachable",))), + (8000, SubMsgResult::Err(_)) => Err(StdError::generic_err(format!("Unreachable",))), + (8001, SubMsgResult::Ok(_)) => Ok(Response::default()), + (8001, SubMsgResult::Err(_)) => { + Err(StdError::generic_err(format!("Funds message failed",))) + } + (9000, SubMsgResult::Ok(o)) => match o.data { + None => Ok(Response::default().set_data(env.contract.address.as_bytes())), + Some(d) => { + let new_data = + String::from_utf8_lossy(d.as_slice()) + " -> " + env.contract.address.as_str(); + Ok(Response::default().set_data(new_data.as_bytes())) + } + }, + (9000, SubMsgResult::Err(_)) => Ok(Response::default().set_data("err".as_bytes())), + (8451, SubMsgResult::Ok(_)) => Ok(Response::new() + .add_attribute_plaintext("attr_reply", "🦄") + .set_data(to_binary("reply")?)), + //(9000, SubMsgResult::Err(_)) => Err(StdError::generic_err("err")), + _ => Err(StdError::generic_err("invalid reply id or result")), + } +} + +fn get(deps: Deps, env: Env) -> StdResult { + let count = count_read(deps.storage).load()?; + let expiration = expiration_read(deps.storage).load()?; + + if env.block.height > expiration { + return Ok(QueryRes::Get { count: 0 }); + } + + Ok(QueryRes::Get { count }) +} + +fn map_string_to_error(error_type: String) -> StdError { + let as_str: &str = &error_type[..]; + match as_str { + "generic_err" => StdError::generic_err("la la 🤯"), + "invalid_base64" => StdError::invalid_base64("ra ra 🤯"), + "invalid_utf8" => StdError::invalid_utf8("ka ka 🤯"), + "not_found" => StdError::not_found("za za 🤯"), + "parse_err" => StdError::parse_err("na na 🤯", "pa pa 🤯"), + "serialize_err" => StdError::serialize_err("ba ba 🤯", "ga ga 🤯"), + // "unauthorized" => StdError::unauthorized(), // dosn't exist in v1 + // "underflow" => StdError::underflow("minuend 🤯", "subtrahend 🤯"), // dosn't exist in v1 + _ => StdError::generic_err("catch-all 🤯"), + } +} + +fn send_external_query_recursion_limit( + deps: Deps, + contract_addr: String, + depth: u8, + code_hash: String, +) -> StdResult { + let result = deps + .querier + .query(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr: contract_addr.clone(), + code_hash: code_hash.clone(), + msg: Binary( + format!( + r#"{{"send_external_query_recursion_limit":{{"to":"{}","code_hash":"{}","depth":{}}}}}"#, + contract_addr.clone().to_string(), + code_hash.clone().to_string(), + depth + 1 + ) + .into_bytes(), + ), + })); + + // 10 is the current recursion limit. + if depth != 10 { + result + } else { + match result { + Err(StdError::GenericErr { msg, .. }) if msg.contains("exceeded_recursion_limit") => { + Ok(String::from("Recursion limit was correctly enforced")) + } + _ => Err(StdError::generic_err( + "Recursion limit was bypassed! this is a bug!", + )), + } + } +} + +#[cfg(feature = "with_floats")] +fn use_floats(x: u8, y: u8) -> Binary { + let res: f64 = (x as f64) / (y as f64); + to_binary(&format!("{}", res)).unwrap() +} + +#[cfg(not(feature = "with_floats"))] +fn use_floats(x: u8, y: u8) -> Binary { + Binary(vec![x, y]) +} + +fn send_external_query(deps: Deps, contract_addr: String, code_hash: String) -> u8 { + let answer: u8 = deps + .querier + .query(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr, + code_hash, + msg: Binary::from(r#"{"receive_external_query":{"num":2}}"#.as_bytes().to_vec()), + })) + .unwrap(); + answer +} + +fn send_external_query_depth_counter( + deps: Deps, + contract_addr: String, + depth: u8, + code_hash: String, +) -> u8 { + if depth == 0 { + return 0; + } + + let answer: u8 = deps + .querier + .query(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr: contract_addr.clone(), + code_hash: code_hash.clone(), + msg: Binary( + format!( + r#"{{"send_external_query_depth_counter":{{"to":"{}","code_hash":"{}","depth":{}}}}}"#, + contract_addr.clone(), + code_hash.clone(), + depth - 1 + ) + .into(), + ), + })) + .unwrap(); + + answer + 1 +} + +fn send_external_query_panic( + deps: DepsMut, + contract_addr: String, + code_hash: String, +) -> StdResult { + let err = deps + .querier + .query::(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr, + msg: Binary::from(r#"{"panic":{}}"#.as_bytes().to_vec()), + code_hash, + })) + .unwrap_err(); + + Err(err) +} + +fn send_external_query_stderror( + deps: DepsMut, + contract_addr: String, + code_hash: String, +) -> StdResult { + let answer = deps + .querier + .query::(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr, + msg: Binary::from( + r#"{"contract_error":{"error_type":"generic_err"}}"# + .as_bytes() + .to_vec(), + ), + code_hash, + })); + + match answer { + Ok(wtf) => Ok(Response::new().set_data(wtf)), + Err(e) => Err(e), + } +} + +fn send_external_query_bad_abi( + deps: DepsMut, + contract_addr: String, + code_hash: String, +) -> StdResult { + let answer = deps + .querier + .query::(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr, + code_hash, + msg: Binary::from( + r#""contract_error":{"error_type":"generic_err"}}"#.as_bytes().to_vec(), + ), + })); + + match answer { + Ok(wtf) => Ok(Response::new().set_data(wtf)), + Err(e) => Err(e), + } +} + +fn send_external_query_bad_abi_receiver( + deps: DepsMut, + contract_addr: String, + code_hash: String, +) -> StdResult { + let answer = deps + .querier + .query::(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr, + msg: Binary::from(r#"{"receive_external_query":{"num":25}}"#.as_bytes().to_vec()), + code_hash, + })); + + match answer { + Ok(wtf) => Ok(Response::new().add_attribute("wtf", wtf)), + Err(e) => Err(e), + } +} + +fn exec_callback_bad_params(contract_addr: String, code_hash: String) -> Response { + Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: contract_addr.clone(), + code_hash, + msg: Binary::from(r#"{"c":{"x":"banana","y":3}}"#.as_bytes().to_vec()), + funds: vec![], + })) +} + +pub fn a( + _deps: DepsMut, + _env: Env, + contract_addr: String, + code_hash: String, + x: u8, + y: u8, +) -> Response { + Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: contract_addr.clone(), + code_hash: code_hash.clone(), + msg: Binary::from( + format!( + "{{\"b\":{{\"x\":{} ,\"y\": {},\"contract_addr\": \"{}\",\"code_hash\": \"{}\" }}}}", + x, + y, + contract_addr.as_str(), + &code_hash + ) + .as_bytes() + .to_vec(), + ), + funds: vec![], + })) + .add_attribute("banana", "🍌") + .set_data(vec![x, y]) +} + +pub fn b( + _deps: DepsMut, + _env: Env, + contract_addr: String, + code_hash: String, + x: u8, + y: u8, +) -> Response { + Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: contract_addr.clone(), + code_hash, + msg: Binary::from( + format!("{{\"c\":{{\"x\":{} ,\"y\": {} }}}}", x + 1, y + 1) + .as_bytes() + .to_vec(), + ), + funds: vec![], + })) + .add_attribute("kiwi", "🥝") + .set_data(vec![x + y]) +} + +pub fn c(_deps: DepsMut, _env: Env, x: u8, y: u8) -> Response { + Response::new() + .add_attribute("watermelon", "🍉") + .set_data(vec![x + y]) +} + +pub fn empty_log_key_value(_deps: DepsMut, _env: Env) -> Response { + Response::new().add_attributes(vec![ + attr("my value is empty", ""), + attr("", "my key is empty"), + ]) +} + +pub fn empty_data(_deps: DepsMut, _env: Env) -> Response { + Response::new().set_data(vec![]) +} + +pub fn unicode_data(_deps: DepsMut, _env: Env) -> Response { + Response::new().set_data("🍆🥑🍄".as_bytes().to_vec()) +} + +pub fn no_data(_deps: DepsMut, _env: Env) -> Response { + Response::new() +} + +pub fn exec_callback_to_init( + _deps: DepsMut, + _env: Env, + code_id: u64, + code_hash: String, +) -> Response { + Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Instantiate { + code_id, + msg: Binary::from("{\"nop\":{}}".as_bytes().to_vec()), + code_hash, + funds: vec![], + label: String::from("hi"), + })) + .add_attribute("instantiating a new contract", "🪂") +} + +fn exec_with_callback_contract_error(contract_addr: String, code_hash: String) -> Response { + Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: contract_addr.clone(), + code_hash, + msg: Binary::from( + r#"{"contract_error":{"error_type":"generic_err"}}"# + .as_bytes() + .to_vec(), + ), + funds: vec![], + })) + .add_attribute("exec with a callback with contract error", "🤷‍♂️") +} + +fn allocate_on_heap(bytes: usize) -> Response { + let mut values: Vec = vec![0; bytes]; + values[bytes - 1] = 1; + + Response::new().set_data("😅".as_bytes().to_vec()) +} + +fn get_state(deps: DepsMut, key: String) -> Response { + let store = PrefixedStorage::new(deps.storage, b"my_prefix"); + + match store.get(key.as_bytes()) { + Some(value) => Response::new().set_data(value), + None => Response::default(), + } +} + +fn set_state(deps: DepsMut, key: String, value: String) -> Response { + let mut store = PrefixedStorage::new(deps.storage, b"my_prefix"); + store.set(key.as_bytes(), value.as_bytes()); + Response::default() +} + +fn remove_state(deps: DepsMut, key: String) -> Response { + let mut store = PrefixedStorage::new(deps.storage, b"my_prefix"); + store.remove(key.as_bytes()); + Response::default() +} + +#[allow(invalid_value)] +#[allow(unused_must_use)] +fn pass_null_pointer_to_imports_should_throw(deps: DepsMut, pass_type: String) -> Response { + let null_ptr_slice: &[u8] = unsafe { MaybeUninit::zeroed().assume_init() }; + + match &pass_type[..] { + "read_db_key" => { + deps.storage.get(null_ptr_slice); + } + "write_db_key" => { + deps.storage.set(null_ptr_slice, b"write value"); + } + "write_db_value" => { + deps.storage.set(b"write key", null_ptr_slice); + } + "remove_db_key" => { + deps.storage.remove(null_ptr_slice); + } + "canonicalize_address_input" => { + deps.api + .addr_canonicalize(unsafe { MaybeUninit::zeroed().assume_init() }); + } + "canonicalize_address_output" => { /* TODO */ } + "humanize_address_input" => { + deps.api + .addr_humanize(unsafe { MaybeUninit::zeroed().assume_init() }); + } + "humanize_address_output" => { /* TODO */ } + "validate_address_input" => { + deps.api + .addr_validate(unsafe { MaybeUninit::zeroed().assume_init() }); + } + "validate_address_output" => { /* TODO */ } + _ => {} + }; + + Response::default() +} + +fn test_canonicalize_address_errors(deps: DepsMut) -> StdResult { + match deps.api.addr_canonicalize("") { + Err(StdError::GenericErr { msg }) => { + if !msg.to_lowercase().contains("input is empty") { + return Err(StdError::generic_err(format!( + "empty address should have failed with 'addr_canonicalize errored: Input is empty; got {:?}'", + msg))); + } + // all is good, continue + } + other => { + return Err(StdError::generic_err( + format!("empty address should have failed with 'addr_canonicalize errored: Input is empty', instead was {:?}", other), + )) + } + } + + match deps.api.addr_canonicalize(" ") { + Err(StdError::GenericErr { msg }) => { + if !msg.to_lowercase().contains("invalid length") { + return Err(StdError::generic_err(format!( + "empty trimmed address should have failed with 'addr_canonicalize errored: invalid length; got {:?}'", + msg))); + } + // all is good, continue + } + other => { + return Err(StdError::generic_err( + format!("empty trimmed address should have failed with 'addr_canonicalize errored: invalid length', instead was: {:?}", other), + )) + } + } + + match deps.api.addr_canonicalize("cosmos1h99hrcc54ms9lxxxx") { + Err(StdError::GenericErr { msg }) + if msg == String::from("addr_canonicalize errored: invalid checksum") => + { + // all is good, continue + } + other => { + return Err(StdError::generic_err( + format!("bad bech32 should have failed with 'addr_canonicalize errored: invalid checksum', instead was {:?}", other), + )) + } + } + + match deps.api.addr_canonicalize("cosmos1h99hrcc54ms9luwpex9kw0rwdt7etvfdyxh6gu") { + Err(StdError::GenericErr { msg }) + if msg == String::from("addr_canonicalize errored: wrong address prefix: \"cosmos\"") => + { + // all is good, continue + } + other => { + return Err(StdError::generic_err( + format!("bad prefix should have failed with 'addr_canonicalize errored: wrong address prefix: \"cosmos\"', instead was {:?}", other), + )) + } + } + + Ok(Response::new().set_data("🤟".as_bytes().to_vec())) +} + +/////////////////////////////// Query /////////////////////////////// + +fn send_external_query_infinite_loop( + deps: Deps, + contract_addr: String, + code_hash: String, +) -> StdResult { + let answer = deps + .querier + .query::(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr: contract_addr.clone(), + code_hash: code_hash.clone(), + msg: Binary::from( + format!( + r#"{{"send_external_query_infinite_loop":{{"to":"{}", "code_hash":"{}"}}}}"#, + contract_addr.clone().to_string(), + &code_hash + ) + .as_bytes() + .to_vec(), + ), + })); + + match answer { + Ok(wtf) => Ok(Binary(wtf.into())), + Err(e) => Err(e), + } +} + +fn write_to_storage_in_query(storage: &dyn Storage) -> StdResult { + #[allow(clippy::cast_ref_to_mut)] + let storage = unsafe { &mut *(storage as *const _ as *mut dyn Storage) }; + storage.set(b"abcd", b"dcba"); + + Ok(Binary(vec![])) +} + +fn remove_from_storage_in_query(storage: &dyn Storage) -> StdResult { + #[allow(clippy::cast_ref_to_mut)] + let storage = unsafe { &mut *(storage as *const _ as *mut dyn Storage) }; + storage.remove(b"abcd"); + + Ok(Binary(vec![])) +} + +//// consts + +const REALLY_LONG: &[u8] = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + +#[entry_point] +pub fn migrate(_deps: DepsMut, _env: Env, msg: MigrateMsg) -> StdResult { + match msg { + MigrateMsg::Nop {} => Ok(Response::default()), + MigrateMsg::StdError {} => Err(StdError::generic_err("this is an std error")), + } +} diff --git a/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/lib.rs b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/lib.rs new file mode 100644 index 000000000..04ade40ed --- /dev/null +++ b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/lib.rs @@ -0,0 +1,3 @@ +pub mod contract; +pub mod msg; +pub mod state; \ No newline at end of file diff --git a/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/msg.rs b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/msg.rs new file mode 100644 index 000000000..7f96f636a --- /dev/null +++ b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/msg.rs @@ -0,0 +1,509 @@ +use cosmwasm_std::{Binary, Coin}; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[serde(rename_all = "snake_case")] +pub struct ExecuteDetails { + pub contract_address: String, + pub contract_hash: String, + pub should_error: bool, + pub msg_id: u64, + pub data: String, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[serde(rename_all = "snake_case")] +pub enum InstantiateMsg { + WasmMsg { + ty: String, + }, + Counter { + counter: u64, + expires: u64, + }, + AddAttributes {}, + AddAttributesWithSubmessage { + id: u64, + }, + AddPlaintextAttributes {}, + AddPlaintextAttributesWithSubmessage { + id: u64, + }, + AddEvents {}, + AddEventsWithSubmessage { + id: u64, + }, + AddMixedAttributesAndEvents {}, + AddMixedAttributesAndEventsWithSubmessage { + id: u64, + }, + MeasureGasForSubmessage { + id: u64, + }, + // These were ported from the v0.10 test-contract: + Nop {}, + Callback { + contract_addr: String, + code_hash: String, + }, + CallbackContractError { + contract_addr: String, + code_hash: String, + }, + ContractError { + error_type: String, + }, + NoLogs {}, + CallbackToInit { + code_id: u64, + code_hash: String, + }, + CallbackBadParams { + contract_addr: String, + code_hash: String, + }, + Panic {}, + SendExternalQueryDepthCounter { + to: String, + depth: u8, + code_hash: String, + }, + SendExternalQueryRecursionLimit { + to: String, + depth: u8, + code_hash: String, + }, + CallToInit { + code_id: u64, + code_hash: String, + label: String, + msg: String, + }, + CallToExec { + addr: String, + code_hash: String, + msg: String, + }, + CallToQuery { + addr: String, + code_hash: String, + msg: String, + }, + BankMsgSend { + amount: Vec, + to: String, + }, + BankMsgBurn { + amount: Vec, + }, + CosmosMsgCustom {}, + SendMultipleFundsToInitCallback { + coins: Vec, + code_id: u64, + code_hash: String, + }, + SendMultipleFundsToExecCallback { + coins: Vec, + to: String, + code_hash: String, + }, + GetEnv {}, + TestRemoveDb {}, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[serde(rename_all = "snake_case")] +pub enum ExecuteMsg { + IncrementTimes { + times: u64, + }, + LastMsgMarkerNop {}, + LastMsgMarker {}, + WasmMsg { + ty: String, + }, + Increment { + addition: u64, + }, + SendFundsWithErrorWithReply {}, + SendFundsWithReply {}, + AddAttributes {}, + AddAttributesWithSubmessage { + id: u64, + }, + AddMoreAttributes {}, + AddPlaintextAttributes {}, + AddPlaintextAttributesWithSubmessage { + id: u64, + }, + AddMorePlaintextAttributes {}, + AddEvents {}, + AddMoreEvents {}, + AddEventsWithSubmessage { + id: u64, + }, + AddMixedAttributesAndEvents {}, + AddMixedAttributesAndEventsWithSubmessage { + id: u64, + }, + AddMoreMixedAttributesAndEvents {}, + AddAttributesFromV010 { + addr: String, + code_hash: String, + id: u64, + }, + GasMeter {}, + GasMeterProxy {}, + TransferMoney { + amount: u64, + }, + RecursiveReply {}, + RecursiveReplyFail {}, + InitNewContract {}, + InitNewContractWithError {}, + SubMsgLoop { + iter: u64, + }, + SubMsgLoopIner { + iter: u64, + }, + MultipleSubMessages {}, + MultipleSubMessagesNoReply {}, + QuickError {}, + MultipleSubMessagesNoReplyWithError {}, + MultipleSubMessagesNoReplyWithPanic {}, + MultipleSubMessagesWithReplyWithError {}, + MultipleSubMessagesWithReplyWithPanic {}, + InitV10 { + code_id: u64, + code_hash: String, + counter: u64, + }, + ExecV10 { + address: String, + code_hash: String, + }, + AddAttributeStep1 {}, + AddAttributeStep2 {}, + AddAttributeStep3 {}, + AddAttributeStep4 {}, + InitV10NoReply { + code_id: u64, + code_hash: String, + counter: u64, + }, + ExecV10NoReply { + address: String, + code_hash: String, + }, + QueryV10 { + address: String, + code_hash: String, + }, + InitV10WithError { + code_id: u64, + code_hash: String, + }, + ExecV10WithError { + address: String, + code_hash: String, + }, + InitV10NoReplyWithError { + code_id: u64, + code_hash: String, + }, + ExecV10NoReplyWithError { + address: String, + code_hash: String, + }, + QueryV10WithError { + address: String, + code_hash: String, + }, + + // These were ported from the v0.10 test-contract: + A { + contract_addr: String, + code_hash: String, + x: u8, + y: u8, + }, + B { + contract_addr: String, + code_hash: String, + x: u8, + y: u8, + }, + C { + x: u8, + y: u8, + }, + UnicodeData {}, + EmptyLogKeyValue {}, + EmptyData {}, + NoData {}, + ContractError { + error_type: String, + }, + NoLogs {}, + CallbackToInit { + code_id: u64, + code_hash: String, + }, + CallbackContractError { + contract_addr: String, + code_hash: String, + }, + CallbackBadParams { + contract_addr: String, + code_hash: String, + }, + SetState { + key: String, + value: String, + }, + GetState { + key: String, + }, + RemoveState { + key: String, + }, + TestCanonicalizeAddressErrors {}, + Panic {}, + AllocateOnHeap { + bytes: u32, + }, + PassNullPointerToImportsShouldThrow { + pass_type: String, + }, + SendExternalQuery { + to: String, + code_hash: String, + }, + SendExternalQueryPanic { + to: String, + code_hash: String, + }, + SendExternalQueryError { + to: String, + code_hash: String, + }, + SendExternalQueryBadAbi { + to: String, + code_hash: String, + }, + SendExternalQueryBadAbiReceiver { + to: String, + code_hash: String, + }, + LogMsgSender {}, + CallbackToLogMsgSender { + to: String, + code_hash: String, + }, + DepositToContract {}, + SendFunds { + amount: u32, + denom: String, + to: String, + from: String, + }, + SendFundsToInitCallback { + amount: u32, + denom: String, + code_id: u64, + code_hash: String, + }, + SendMultipleFundsToInitCallback { + coins: Vec, + code_id: u64, + code_hash: String, + }, + SendFundsToExecCallback { + amount: u32, + denom: String, + to: String, + code_hash: String, + }, + SendMultipleFundsToExecCallback { + coins: Vec, + to: String, + code_hash: String, + }, + ValidateAddress { + addr: String, + }, + Sleep { + ms: u64, + }, + SendExternalQueryDepthCounter { + to: String, + code_hash: String, + depth: u8, + }, + SendExternalQueryRecursionLimit { + to: String, + code_hash: String, + depth: u8, + }, + WithFloats { + x: u8, + y: u8, + }, + CallToInit { + code_id: u64, + code_hash: String, + label: String, + msg: String, + }, + CallToExec { + addr: String, + code_hash: String, + msg: String, + }, + CallToQuery { + addr: String, + code_hash: String, + msg: String, + }, + StoreReallyLongKey {}, + StoreReallyShortKey {}, + StoreReallyLongValue {}, + Secp256k1Verify { + pubkey: Binary, + sig: Binary, + msg_hash: Binary, + iterations: u32, + }, + Secp256k1VerifyFromCrate { + pubkey: Binary, + sig: Binary, + msg_hash: Binary, + iterations: u32, + }, + Ed25519Verify { + pubkey: Binary, + sig: Binary, + msg: Binary, + iterations: u32, + }, + Ed25519BatchVerify { + pubkeys: Vec, + sigs: Vec, + msgs: Vec, + iterations: u32, + }, + Secp256k1RecoverPubkey { + msg_hash: Binary, + sig: Binary, + recovery_param: u8, + iterations: u32, + }, + Secp256k1Sign { + msg: Binary, + privkey: Binary, + iterations: u32, + }, + Ed25519Sign { + msg: Binary, + privkey: Binary, + iterations: u32, + }, + BankMsgSend { + amount: Vec, + to: String, + }, + BankMsgBurn { + amount: Vec, + }, + CosmosMsgCustom {}, + GetEnv {}, + ExecuteMultipleContracts { + details: Vec, + }, + #[serde(rename = "ibc_lifecycle_complete")] + IBCLifecycleComplete(IBCLifecycleComplete), +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub enum IBCLifecycleComplete { + #[serde(rename = "ibc_ack")] + IBCAck { + /// The source channel (secret side) of the IBC packet + channel: String, + /// The sequence number that the packet was sent with + sequence: u64, + /// String encoded version of the ack as seen by OnAcknowledgementPacket(..) + ack: String, + /// Weather an ack is a success of failure according to the transfer spec + success: bool, + }, + #[serde(rename = "ibc_timeout")] + IBCTimeout { + /// The source channel (secret side) of the IBC packet + channel: String, + /// The sequence number that the packet was sent with + sequence: u64, + }, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum QueryMsg { + Get {}, + // These were ported from the v0.10 test-contract: + ContractError { + error_type: String, + }, + Panic {}, + ReceiveExternalQuery { + num: u8, + }, + ReceiveExternalQueryV1 { + num: u8, + }, + SendExternalQueryInfiniteLoop { + to: String, + code_hash: String, + }, + WriteToStorage {}, + RemoveFromStorage {}, + SendExternalQueryDepthCounter { + to: String, + depth: u8, + code_hash: String, + }, + SendExternalQueryRecursionLimit { + to: String, + depth: u8, + code_hash: String, + }, + CallToQuery { + addr: String, + code_hash: String, + msg: String, + }, + GetContractVersion {}, + GetEnv {}, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum QueryRes { + Get { count: u64 }, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum ExternalMessages { + GetCountFromV1 {}, + QueryFromV1WithError {}, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum MigrateMsg { + Nop {}, + StdError {}, +} diff --git a/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/state.rs b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/state.rs new file mode 100644 index 000000000..ada90fcec --- /dev/null +++ b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/state.rs @@ -0,0 +1,23 @@ +use cosmwasm_std::Storage; +use cosmwasm_storage::{singleton, singleton_read, ReadonlySingleton, Singleton}; + +pub const COUNT_KEY: &[u8] = b"count"; +pub const EXPIRATION_KEY: &[u8] = b"expire"; +pub const PREFIX_TEST: &[u8] = b"prefix"; +pub const TEST_KEY: &[u8] = b"key"; + +pub fn count(storage: &mut dyn Storage) -> Singleton { + singleton(storage, COUNT_KEY) +} + +pub fn count_read(storage: &dyn Storage) -> ReadonlySingleton { + singleton_read(storage, COUNT_KEY) +} + +pub fn expiration(storage: &mut dyn Storage) -> Singleton { + singleton(storage, EXPIRATION_KEY) +} + +pub fn expiration_read(storage: &dyn Storage) -> ReadonlySingleton { + singleton_read(storage, EXPIRATION_KEY) +} diff --git a/go-cosmwasm/types/stderror.go b/go-cosmwasm/types/stderror.go index 99cf7626e..dc8bf8763 100644 --- a/go-cosmwasm/types/stderror.go +++ b/go-cosmwasm/types/stderror.go @@ -53,6 +53,23 @@ func (a StdError) Error() string { } } +func (a StdError) IsEmpty() bool { + switch { + case a.GenericErr != nil: + case a.InvalidBase64 != nil: + case a.InvalidUtf8 != nil: + case a.NotFound != nil: + case a.ParseErr != nil: + case a.SerializeErr != nil: + case a.Unauthorized != nil: + case a.Underflow != nil: + return false + default: + return true + } + return true +} + type GenericErr struct { Msg string `json:"msg,omitempty"` } diff --git a/x/compute/internal/keeper/secret_contracts_migrate_test.go b/x/compute/internal/keeper/secret_contracts_migrate_test.go index a5e8bcf6a..574531fd3 100644 --- a/x/compute/internal/keeper/secret_contracts_migrate_test.go +++ b/x/compute/internal/keeper/secret_contracts_migrate_test.go @@ -1,15 +1,30 @@ package keeper import ( + "encoding/base64" + "encoding/binary" + "encoding/hex" + "encoding/json" + "fmt" "math" + "os" + "strings" "testing" + sdk "github.com/cosmos/cosmos-sdk/types" + + v010types "github.com/scrtlabs/SecretNetwork/go-cosmwasm/types/v010" + "golang.org/x/exp/slices" + + cosmwasm "github.com/scrtlabs/SecretNetwork/go-cosmwasm/types" "github.com/stretchr/testify/require" - sdk "github.com/cosmos/cosmos-sdk/types" + ibctransfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + ibcclienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" + ibcchanneltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" ) -func TestMigrateContract(t *testing.T) { +func TestContractAfterMigrate(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[migrateContractV1], sdk.NewCoins()) newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[migrateContractV2], walletA) @@ -46,7 +61,7 @@ func TestContractInfoNullAdmin(t *testing.T) { require.Equal(t, sdk.AccAddress{}.String(), info.Admin) } -func TestMigrateWithStorage(t *testing.T) { +func TestWithStorageAfterMigrate(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[migrateContractV1], sdk.NewCoins()) newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[migrateContractV2], walletA) @@ -65,7 +80,7 @@ func TestMigrateWithStorage(t *testing.T) { require.Empty(t, data) } -func TestMigrateContractFromDifferentAccount(t *testing.T) { +func TestContractFromDifferentAccountAfterMigrate(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, WalletB, privKeyB := setupTest(t, TestContractPaths[migrateContractV1], sdk.NewCoins()) newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[migrateContractV2], walletA) @@ -76,7 +91,7 @@ func TestMigrateContractFromDifferentAccount(t *testing.T) { require.NotNil(t, err) } -func TestMigrateVmError(t *testing.T) { +func TestVmErrorAfterMigrate(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[migrateContractV1], sdk.NewCoins()) newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[migrateContractV2], walletA) @@ -87,7 +102,7 @@ func TestMigrateVmError(t *testing.T) { require.Contains(t, err.Error(), "Error parsing into type migrate_contract_v2::msg::MigrateMsg: unknown variant `yolo`") } -func TestMigrateStdError(t *testing.T) { +func TestStdErrorAfterMigrate(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[migrateContractV1], sdk.NewCoins()) newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[migrateContractV2], walletA) @@ -101,3 +116,2518 @@ func TestMigrateStdError(t *testing.T) { _, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"std_error":{}}`, true, true, math.MaxUint64) require.Equal(t, err.Error(), "encrypted: Generic error: this is an std error") } + +/// copy of exec tests but with a migrate twist: + +func TestStateAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + _, _, _, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"set_state":{"key":"banana","value":"🍌"}}`, true, true, defaultGasForTests, 0) + require.Empty(t, execErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + + _, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, err) + + _, _, data, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"get_state":{"key":"banana"}}`, true, true, defaultGasForTests, 0) + require.Empty(t, execErr) + require.Equal(t, "🍌", string(data)) + + _, _, _, _, _, execErr = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"remove_state":{"key":"banana"}}`, true, true, defaultGasForTests, 0) + require.Empty(t, execErr) + + _, _, data, _, _, execErr = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"get_state":{"key":"banana"}}`, true, true, defaultGasForTests, 0) + require.Empty(t, execErr) + require.Empty(t, data) + + _, _, _, _, _, execErr = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"set_state":{"key":"banana","value":"🍌"}}`, true, true, defaultGasForTests, 0) + require.Empty(t, execErr) + + _, _, data, _, _, execErr = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"get_state":{"key":"banana"}}`, true, true, defaultGasForTests, 0) + require.Empty(t, execErr) + require.Equal(t, "🍌", string(data)) +} + +func TestAddrValidateFunctionAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + _, _, data, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"validate_address":{"addr":"%s"}}`, contractAddress), true, true, defaultGasForTests, 0) + require.Empty(t, err) + + resp, aErr := sdk.AccAddressFromBech32(string(data)) + require.Empty(t, aErr) + + require.Equal(t, resp, contractAddress) + + _, _, data, _, _, err = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"validate_address":{"addr":"secret18vd8fpwxzck93qlwghaj6arh4p7c5nyf7hmag8"}}`), true, true, defaultGasForTests, 0) + require.Equal(t, string(data), "\"Apple\"") +} + +func TestRandomEnvAfterMigrate(t *testing.T) { + t.SkipNow() // TODO this shuold work... + + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + _, _, _, execEvents, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"get_env":{}}`, true, true, defaultGasForTests, 1) + require.Empty(t, execErr) + + execEvent := execEvents[0] + envAttributeIndex := slices.IndexFunc(execEvent, func(c v010types.LogAttribute) bool { return c.Key == "env" }) + envAttribute := execEvent[envAttributeIndex] + + var actualExecEnv cosmwasm.Env + json.Unmarshal([]byte(envAttribute.Value), &actualExecEnv) + + expectedV1EnvExec := fmt.Sprintf( + `{"block":{"height":%d,"time":"%d","chain_id":"%s","random":"%s"},"transaction":null,"contract":{"address":"%s","code_hash":"%s"}}`, + ctx.BlockHeight(), + // env.block.time is nanoseconds since unix epoch + ctx.BlockTime().UnixNano(), + ctx.ChainID(), + base64.StdEncoding.EncodeToString(actualExecEnv.Block.Random), + contractAddress.String(), + calcCodeHash(TestContractPaths[v1MigratedContract]), + ) + + requireEventsInclude(t, + execEvents, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + { + Key: "env", + Value: expectedV1EnvExec, + }, + }, + }, + ) +} + +func TestEnvAfterMigrate(t *testing.T) { + type ReturnedV1MessageInfo struct { + Sender cosmwasm.HumanAddress `json:"sender"` + SentFunds cosmwasm.Coins `json:"funds"` + // Random string `json:"random"` + } + + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, initEvents, initErr := initHelperImpl(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"get_env":{}}`, true, true, defaultGasForTests, -1, sdk.NewCoins(sdk.NewInt64Coin("denom", 1))) + require.Empty(t, initErr) + require.Len(t, initEvents, 1) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + expectedV1Env := fmt.Sprintf( + `{"block":{"height":%d,"time":"%d","chain_id":"%s"},"transaction":null,"contract":{"address":"%s","code_hash":"%s"}}`, + ctx.BlockHeight(), + // env.block.time is nanoseconds since unix epoch + ctx.BlockTime().UnixNano(), + ctx.ChainID(), + contractAddress.String(), + calcCodeHash(TestContractPaths[v1MigratedContract]), + ) + + _, _, _, execEvents, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"get_env":{}}`, true, true, defaultGasForTests, 1) + require.Empty(t, execErr) + + if true { + requireEventsInclude(t, + execEvents, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + { + Key: "env", + Value: expectedV1Env, + }, + }, + }, + ) + + execEvent := execEvents[0] + infoLogAttributeIndex := slices.IndexFunc(execEvent, func(c v010types.LogAttribute) bool { return c.Key == "info" }) + infoLogAttribute := execEvent[infoLogAttributeIndex] + + var actualMessageInfo ReturnedV1MessageInfo + _ = json.Unmarshal([]byte(infoLogAttribute.Value), &actualMessageInfo) + + require.Equal(t, walletA.String(), actualMessageInfo.Sender) + require.Equal(t, cosmwasm.Coins{{Denom: "denom", Amount: "1"}}, actualMessageInfo.SentFunds) + + // disabling random tests + // require.Len(t, actualMessageInfo.Random, 44) + // require.NotEqual(t, firstRandom, actualMessageInfo.Random) + } else { + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + { + Key: "env", + Value: fmt.Sprintf( + `{"block":{"height":%d,"time":%d,"chain_id":"%s"},"message":{"sender":"%s","sent_funds":[{"denom":"denom","amount":"1"}]},"contract":{"address":"%s"},"contract_key":null,"contract_code_hash":"%s"}`, + ctx.BlockHeight(), + // env.block.time is seconds since unix epoch + ctx.BlockTime().Unix(), + ctx.ChainID(), + walletA.String(), + contractAddress.String(), + calcCodeHash(TestContractPaths[v1MigratedContract]), + ), + }, + }, + }, + execEvents, + ) + } + + if true { + // only env (no msg info) in v1 query + queryRes, qErr := queryHelper(t, keeper, ctx, contractAddress, `{"get_env":{}}`, true, false, math.MaxUint64) + require.Empty(t, qErr) + + require.Equal(t, expectedV1Env, queryRes) + } else { + // no env or msg info in v0.10 query + } +} + +func TestNestedAttributeAfterMigrate(t *testing.T) { + // For more reference: https://github.com/scrtlabs/SecretNetwork/issues/1235 + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + _, _, data, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_attribute_step1":{}}`, true, true, 10*defaultGasForTests, 0) + require.Empty(t, err) + + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🦄"}, + }, + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr2", Value: "🦄"}, + }, + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr3", Value: "🦄"}, + }, + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr4", Value: "🦄"}, + }, + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr_reply", Value: "🦄"}, + }, + }, + events, + ) + + require.Equal(t, string(data), "\"reply\"") +} + +func TestEmptyLogKeyValueAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + _, _, _, execEvents, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"empty_log_key_value":{}}`, true, true, defaultGasForTests, 0) + + require.Empty(t, execErr) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "my value is empty", Value: ""}, + {Key: "", Value: "my key is empty"}, + }, + }, + execEvents, + ) +} + +func TestExecNoLogsAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + _, _, _, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"no_logs":{}}`, true, true, defaultGasForTests, 0) + + require.Empty(t, err) +} + +func TestEmptyDataAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + _, _, data, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"empty_data":{}}`, true, true, defaultGasForTests, 0) + + require.Empty(t, err) + require.Empty(t, data) +} + +func TestNoDataAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + _, _, data, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"no_data":{}}`, true, true, defaultGasForTests, 0) + + require.Empty(t, err) + require.Empty(t, data) +} + +func TestUnicodeDataAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + _, _, data, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"unicode_data":{}}`, true, true, defaultGasForTests, 0) + + require.Empty(t, err) + require.Equal(t, "🍆🥑🍄", string(data)) +} + +func TestSecp256k1VerifyAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + // https://paulmillr.com/noble/ + + t.Run("CorrectCompactPubkey", func(t *testing.T) { + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"A0ZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo//","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, true, defaultGasForTests, 0) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + events, + ) + }) + t.Run("CorrectLongPubkey", func(t *testing.T) { + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"BEZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo///ne03QpL+5WFHztzVceB3WD4QY/Ipl0UkHr/R8kDpVk=","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, true, defaultGasForTests, 0) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + events, + ) + }) + t.Run("IncorrectMsgHashCompactPubkey", func(t *testing.T) { + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"A0ZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo//","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzas="}}`, true, true, defaultGasForTests, 0) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + events, + ) + }) + t.Run("IncorrectMsgHashLongPubkey", func(t *testing.T) { + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"BEZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo///ne03QpL+5WFHztzVceB3WD4QY/Ipl0UkHr/R8kDpVk=","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzas="}}`, true, true, defaultGasForTests, 0) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + events, + ) + }) + t.Run("IncorrectSigCompactPubkey", func(t *testing.T) { + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"A0ZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo//","sig":"rhZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, true, defaultGasForTests, 0) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + events, + ) + }) + t.Run("IncorrectSigLongPubkey", func(t *testing.T) { + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"BEZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo///ne03QpL+5WFHztzVceB3WD4QY/Ipl0UkHr/R8kDpVk=","sig":"rhZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, true, defaultGasForTests, 0) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + events, + ) + }) + t.Run("IncorrectCompactPubkey", func(t *testing.T) { + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"AoSdDHH9J0Bfb9pT8GFn+bW9cEVkgIh4bFsepMWmczXc","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, true, defaultGasForTests, 0) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + events, + ) + }) + t.Run("IncorrectLongPubkey", func(t *testing.T) { + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"BISdDHH9J0Bfb9pT8GFn+bW9cEVkgIh4bFsepMWmczXcFWl11YCgu65hzvNDQE2Qo1hwTMQ/42Xif8O/MrxzvxI=","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, true, defaultGasForTests, 0) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + events, + ) + }) +} + +func TestEd25519VerifyAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + // https://paulmillr.com/noble/ + t.Run("Correct", func(t *testing.T) { + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_verify":{"iterations":1,"pubkey":"LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","sig":"8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","msg":"YXNzYWYgd2FzIGhlcmU="}}`, true, true, defaultGasForTests, 0) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + events, + ) + }) + t.Run("IncorrectMsg", func(t *testing.T) { + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_verify":{"iterations":1,"pubkey":"LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","sig":"8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","msg":"YXNzYWYgd2FzIGhlcmUK"}}`, true, true, defaultGasForTests, 0) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + events, + ) + }) + t.Run("IncorrectSig", func(t *testing.T) { + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_verify":{"iterations":1,"pubkey":"LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","sig":"8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDw==","msg":"YXNzYWYgd2FzIGhlcmU="}}`, true, true, defaultGasForTests, 0) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + events, + ) + }) + t.Run("IncorrectPubkey", func(t *testing.T) { + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_verify":{"iterations":1,"pubkey":"DV1lgRdKw7nt4hvl8XkGZXMzU9S3uM9NLTK0h0qMbUs=","sig":"8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","msg":"YXNzYWYgd2FzIGhlcmU="}}`, true, true, defaultGasForTests, 0) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + events, + ) + }) +} + +func TestEd25519BatchVerifyAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + // https://paulmillr.com/noble/ + t.Run("Correct", func(t *testing.T) { + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg=="],"msgs":["YXNzYWYgd2FzIGhlcmU="]}}`, true, true, defaultGasForTests, 0) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + events, + ) + }) + t.Run("100Correct", func(t *testing.T) { + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg=="],"msgs":["YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU="]}}`, true, true, defaultGasForTests, 0) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + events, + ) + }) + t.Run("IncorrectPubkey", func(t *testing.T) { + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["DV1lgRdKw7nt4hvl8XkGZXMzU9S3uM9NLTK0h0qMbUs="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg=="],"msgs":["YXNzYWYgd2FzIGhlcmU="]}}`, true, true, defaultGasForTests, 0) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + events, + ) + }) + t.Run("IncorrectMsg", func(t *testing.T) { + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg=="],"msgs":["YXNzYWYgd2FzIGhlcmUK"]}}`, true, true, defaultGasForTests, 0) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + events, + ) + }) + t.Run("IncorrectSig", func(t *testing.T) { + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDw=="],"msgs":["YXNzYWYgd2FzIGhlcmU="]}}`, true, true, defaultGasForTests, 0) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + events, + ) + }) + t.Run("CorrectEmptySigsEmptyMsgsOnePubkey", func(t *testing.T) { + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA="],"sigs":[],"msgs":[]}}`, true, true, defaultGasForTests, 0) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + events, + ) + }) + t.Run("CorrectEmpty", func(t *testing.T) { + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":[],"sigs":[],"msgs":[]}}`, true, true, defaultGasForTests, 0) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + events, + ) + }) + t.Run("CorrectEmptyPubkeysEmptySigsOneMsg", func(t *testing.T) { + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":[],"sigs":[],"msgs":["YXNzYWYgd2FzIGhlcmUK"]}}`, true, true, defaultGasForTests, 0) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + events, + ) + }) + t.Run("CorrectMultisig", func(t *testing.T) { + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","2ukhmWRNmcgCrB9fpLP9/HZVuJn6AhpITf455F4GsbM="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","bp/N4Ub2WFk9SE9poZVEanU1l46WMrFkTd5wQIXi6QJKjvZUi7+GTzmTe8y2yzgpBI+GWQmt0/QwYbnSVxq/Cg=="],"msgs":["YXNzYWYgd2FzIGhlcmU="]}}`, true, true, defaultGasForTests, 0) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + events, + ) + }) + t.Run("CorrectMultiMsgOneSigner", func(t *testing.T) { + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["2ukhmWRNmcgCrB9fpLP9/HZVuJn6AhpITf455F4GsbM="],"sigs":["bp/N4Ub2WFk9SE9poZVEanU1l46WMrFkTd5wQIXi6QJKjvZUi7+GTzmTe8y2yzgpBI+GWQmt0/QwYbnSVxq/Cg==","uuNxLEzAYDbuJ+BiYN94pTqhD7UhvCJNbxAbnWz0B9DivkPXmqIULko0DddP2/tVXPtjJ90J20faiWCEC3QkDg=="],"msgs":["YXNzYWYgd2FzIGhlcmU=","cGVhY2Ugb3V0"]}}`, true, true, defaultGasForTests, 0) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + events, + ) + }) +} + +func TestSecp256k1RecoverPubkeyAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + // https://paulmillr.com/noble/ + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_recover_pubkey":{"iterations":1,"recovery_param":0,"sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, true, defaultGasForTests, 0) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "A0ZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo//"}, + }, + }, + events, + ) + + _, _, _, events, _, err = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_recover_pubkey":{"iterations":1,"recovery_param":1,"sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, true, defaultGasForTests, 0) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "Ams198xOCEVnc/ESvxF2nxnE3AVFO8ahB22S1ZgX2vSR"}, + }, + }, + events, + ) +} + +func TestSecp256k1SignAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + // priv iadRiuRKNZvAXwolxqzJvr60uiMDJTxOEzEwV8OK2ao= + // pub ArQojoh5TVlSSNA1HFlH5HcQsv0jnrpeE7hgwR/N46nS + // msg d2VuIG1vb24= + // msg_hash K9vGEuzCYCUcIXlhMZu20ke2K4mJhreguYct5MqAzhA= + + // https://paulmillr.com/noble/ + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_sign":{"iterations":1,"msg":"d2VuIG1vb24=","privkey":"iadRiuRKNZvAXwolxqzJvr60uiMDJTxOEzEwV8OK2ao="}}`, true, true, defaultGasForTests, 0) + require.Empty(t, err) + + signature := events[0][1].Value + + _, _, _, events, _, err = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"secp256k1_verify":{"iterations":1,"pubkey":"ArQojoh5TVlSSNA1HFlH5HcQsv0jnrpeE7hgwR/N46nS","sig":"%s","msg_hash":"K9vGEuzCYCUcIXlhMZu20ke2K4mJhreguYct5MqAzhA="}}`, signature), true, true, defaultGasForTests, 0) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + events, + ) +} + +func TestEd25519SignAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + // priv z01UNefH2yjRslwZMmcHssdHmdEjzVvbxjr+MloUEYo= + // pub jh58UkC0FDsiupZBLdaqKUqYubJbk3LDaruZiJiy0Po= + // msg d2VuIG1vb24= + // msg_hash K9vGEuzCYCUcIXlhMZu20ke2K4mJhreguYct5MqAzhA= + + // https://paulmillr.com/noble/ + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_sign":{"iterations":1,"msg":"d2VuIG1vb24=","privkey":"z01UNefH2yjRslwZMmcHssdHmdEjzVvbxjr+MloUEYo="}}`, true, true, defaultGasForTests, 0) + require.Empty(t, err) + + signature := events[0][1].Value + + _, _, _, events, _, err = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"ed25519_verify":{"iterations":1,"pubkey":"jh58UkC0FDsiupZBLdaqKUqYubJbk3LDaruZiJiy0Po=","sig":"%s","msg":"d2VuIG1vb24="}}`, signature), true, true, defaultGasForTests, 0) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + events, + ) +} + +func TestSleepAfterMigrate(t *testing.T) { + for _, testContract := range testContracts { + t.Run(testContract.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + _, _, _, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"sleep":{"ms":3000}}`, false, true, defaultGasForTests, 0) + + require.Error(t, execErr) + require.Error(t, execErr.GenericErr) + require.Contains(t, execErr.GenericErr.Msg, "the contract panicked") + }) + } +} + +func TestAllocateOnHeapFailBecauseMemoryLimitAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + _, _, data, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"allocate_on_heap":{"bytes":13631488}}`, false, true, defaultGasForTests, 0) + + // this should fail with memory error because 13MiB is more than the allowed 12MiB + + require.Empty(t, data) + + require.NotNil(t, execErr.GenericErr) + require.Contains(t, execErr.GenericErr.Msg, "the contract panicked") +} + +func TestAllocateOnHeapFailBecauseGasLimitAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + // ensure we get an out of gas panic + defer func() { + r := recover() + require.NotNil(t, r) + _, ok := r.(sdk.ErrorOutOfGas) + require.True(t, ok, "%+v", r) + }() + + _, _, _, _, _, _ = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"allocate_on_heap":{"bytes":1073741824}}`, false, true, 100_000, 0) + + // this should fail with out of gas because 1GiB will ask for + // 134,217,728 gas units (8192 per page times 16,384 pages) + // the default gas limit in ctx is 200,000 which translates into + // 20,000,000 WASM gas units, so before the memory_grow opcode is reached + // the gas metering sees a request that'll cost 134mn and the limit + // is 20mn, so it throws an out of gas exception + + require.True(t, false) +} + +func TestAllocateOnHeapMoreThanSGXHasFailBecauseMemoryLimitAfterMigrate(t *testing.T) { + for _, testContract := range testContracts { + t.Run(testContract.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + _, _, data, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"allocate_on_heap":{"bytes":1073741824}}`, false, true, 9_000_000, 0) + + // this should fail with memory error because 1GiB is more + // than the allowed 12MiB, gas is 9mn so WASM gas is 900mn + // which is bigger than the 134mn from the previous test + + require.Empty(t, data) + + require.NotNil(t, execErr.GenericErr) + require.Contains(t, execErr.GenericErr.Msg, "the contract panicked") + }) + } +} + +func TestPassNullPointerToImportsAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + tests := []string{ + "read_db_key", + "write_db_key", + "write_db_value", + "remove_db_key", + "canonicalize_address_input", + "humanize_address_input", + } + + for _, passType := range tests { + t.Run(passType, func(t *testing.T) { + _, _, _, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"pass_null_pointer_to_imports_should_throw":{"pass_type":"%s"}}`, passType), false, true, defaultGasForTests, 0) + + require.NotNil(t, execErr.GenericErr) + if true { + require.Contains(t, execErr.GenericErr.Msg, "execute contract failed") + } else { + require.Contains(t, execErr.GenericErr.Msg, "failed to read memory") + } + }) + } +} + +func TestV1ReplyLoopAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + _, _, data, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"sub_msg_loop":{"iter": 10}}`, true, true, math.MaxUint64, 0) + + require.Empty(t, err) + require.Equal(t, uint32(20), binary.BigEndian.Uint32(data)) +} + +func TestBankMsgSendAfterMigrate(t *testing.T) { + for _, test := range []struct { + description string + input string + isSuccuss bool + errorMsg string + balancesBefore string + balancesAfter string + }{ + { + description: "regular", + input: `[{"amount":"2","denom":"denom"}]`, + isSuccuss: true, + balancesBefore: "5000assaf,200000denom 5000assaf,5000denom", + balancesAfter: "4998assaf,199998denom 5000assaf,5002denom", + }, + { + description: "multi-coin", + input: `[{"amount":"1","denom":"assaf"},{"amount":"1","denom":"denom"}]`, + isSuccuss: true, + balancesBefore: "5000assaf,200000denom 5000assaf,5000denom", + balancesAfter: "4998assaf,199998denom 5001assaf,5001denom", + }, + { + description: "zero", + input: `[{"amount":"0","denom":"denom"}]`, + isSuccuss: false, + errorMsg: "encrypted: dispatch: submessages: 0denom: invalid coins", + balancesBefore: "5000assaf,200000denom 5000assaf,5000denom", + balancesAfter: "4998assaf,199998denom 5000assaf,5000denom", + }, + { + description: "insufficient funds", + input: `[{"amount":"3","denom":"denom"}]`, + isSuccuss: false, + balancesBefore: "5000assaf,200000denom 5000assaf,5000denom", + balancesAfter: "4998assaf,199998denom 5000assaf,5000denom", + errorMsg: "encrypted: dispatch: submessages: 2denom is smaller than 3denom: insufficient funds", + }, + { + description: "non-existing denom", + input: `[{"amount":"1","denom":"blabla"}]`, + isSuccuss: false, + balancesBefore: "5000assaf,200000denom 5000assaf,5000denom", + balancesAfter: "4998assaf,199998denom 5000assaf,5000denom", + errorMsg: "encrypted: dispatch: submessages: 0blabla is smaller than 1blabla: insufficient funds", + }, + { + description: "none", + input: `[]`, + isSuccuss: true, + balancesBefore: "5000assaf,200000denom 5000assaf,5000denom", + balancesAfter: "4998assaf,199998denom 5000assaf,5000denom", + }, + } { + t.Run(test.description, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, walletB, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins(sdk.NewInt64Coin("assaf", 5000))) + + walletACoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletA) + walletBCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletB) + + require.Equal(t, test.balancesBefore, walletACoinsBefore.String()+" "+walletBCoinsBefore.String()) + + var err cosmwasm.StdError + var contractAddress sdk.AccAddress + + _, _, contractAddress, _, _ = initHelperImpl(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, false, true, defaultGasForTests, -1, sdk.NewCoins(sdk.NewInt64Coin("denom", 2), sdk.NewInt64Coin("assaf", 2))) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + _, _, _, _, _, err = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"bank_msg_send":{"to":"%s","amount":%s}}`, walletB.String(), test.input), false, true, math.MaxUint64, 0) + + if test.isSuccuss { + require.Empty(t, err) + } else { + require.NotEmpty(t, err) + require.Equal(t, err.Error(), test.errorMsg) + } + + walletACoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletA) + walletBCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletB) + + require.Equal(t, test.balancesAfter, walletACoinsAfter.String()+" "+walletBCoinsAfter.String()) + }) + } +} + +func TestSendFundsAfterMigrate(t *testing.T) { + for _, callTypes := range multisetsFrom([]string{"init", "exec", "user"}, 2) { + originType, destinationType := callTypes[0], callTypes[1] + + t.Run(originType+"->"+destinationType, func(t *testing.T) { + alreadyTested := make(map[string]bool) + alreadyTested["useruser->useruser"] = true // we are only testing contracts here + for _, currentSubjects := range multisetsFrom(testContracts, 2) { + originVersion, destinationVersion := currentSubjects[0], currentSubjects[1] + + // users don't have versions, so skip the repeating tests (user v1 = user v10) + if originType == "user" { + originVersion.CosmWasmVersion = "user" + } + if destinationType == "user" { + destinationVersion.CosmWasmVersion = "user" + } + testTitle := originType + originVersion.CosmWasmVersion + "->" + destinationType + destinationVersion.CosmWasmVersion + if _, value := alreadyTested[testTitle]; value { + continue + } + alreadyTested[testTitle] = true + + t.Run(testTitle, func(t *testing.T) { + for _, test := range []struct { + description string + coinsToSend string + isSuccess bool + errorMsg string + balancesBefore string + balancesAfter string + destinationBalancesAfter string + }{ + { + description: "one, has all", + coinsToSend: `20one`, + isSuccess: true, + balancesBefore: "200000denom,5000one", + balancesAfter: "200000denom,4980one", + destinationBalancesAfter: "20one", + }, + { + description: "one, missing", + coinsToSend: `20one`, + isSuccess: false, + errorMsg: "0one is smaller than 20one: insufficient funds", + balancesBefore: "5000another", + balancesAfter: "5000another", + destinationBalancesAfter: "", + }, + { + description: "one, not enough", + coinsToSend: `20one`, + isSuccess: false, + errorMsg: "19one is smaller than 20one: insufficient funds", + balancesBefore: "5000another,19one", + balancesAfter: "5000another,19one", + destinationBalancesAfter: "", + }, + { + description: "zero", + coinsToSend: ``, + isSuccess: true, + balancesBefore: "5000assaf,200000denom", + balancesAfter: "5000assaf,200000denom", + destinationBalancesAfter: "", + }, + { + description: "multi-coin, has all", + coinsToSend: `130assaf,15denom`, + isSuccess: true, + balancesBefore: "5000assaf,200000denom", + balancesAfter: "4870assaf,199985denom", + destinationBalancesAfter: "130assaf,15denom", + }, + { + description: "multi-coin, missing one", + coinsToSend: `130assaf,15denom`, + isSuccess: false, + errorMsg: "0assaf is smaller than 130assaf: insufficient funds", + balancesBefore: "200000denom", + balancesAfter: "200000denom", + destinationBalancesAfter: "", + }, + { + description: "multi-coin, not enough of one of them", + coinsToSend: `130assaf,15denom`, + isSuccess: false, + errorMsg: "10denom is smaller than 15denom: insufficient funds", + balancesBefore: "5000assaf,10denom", + balancesAfter: "5000assaf,10denom", + destinationBalancesAfter: "", + }, + { + description: "multi-coin, not enough of all of them", + coinsToSend: `130assaf,15denom`, + isSuccess: false, + errorMsg: "12assaf is smaller than 130assaf: insufficient funds", + balancesBefore: "12assaf,10denom", + balancesAfter: "12assaf,10denom", + destinationBalancesAfter: "", + }, + } { + t.Run(test.description, func(t *testing.T) { + ctx, keeper, helperWallet, helperPrivKey, _, _ := setupBasicTest(t, sdk.NewCoins(sdk.NewInt64Coin("assaf", 5000))) + + fundingWallet, fundingWalletPrivKey := CreateFakeFundedAccount(ctx, keeper.accountKeeper, keeper.bankKeeper, stringToCoins(test.balancesBefore)) + receivingWallet, _ := CreateFakeFundedAccount(ctx, keeper.accountKeeper, keeper.bankKeeper, sdk.NewCoins()) + + // verify that the account was funded correctly + fundingWalletCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, fundingWallet) + require.Equal(t, test.balancesBefore, fundingWalletCoinsBefore.String()) + + var originCodeId uint64 + if originType != "user" { + originCodeId, _ = uploadCode(ctx, t, keeper, originVersion.WasmFilePath, helperWallet) + } + + var destinationCodeId uint64 + var destinationHash string + var destinationAddr sdk.AccAddress + + // prepare receiving contract + if destinationType != "user" { + destinationCodeId, destinationHash = uploadCode(ctx, t, keeper, destinationVersion.WasmFilePath, helperWallet) + + if destinationType == "exec" { + _, _, destinationAddr, _, _ = initHelperImpl(t, keeper, ctx, destinationCodeId, helperWallet, helperWallet, helperPrivKey, `{"nop":{}}`, false, destinationVersion.IsCosmWasmV1, defaultGasForTests, -1, sdk.NewCoins()) + + if destinationVersion.IsCosmWasmV1 && destinationAddr != nil { + newCodeId, newDestinationHash := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], helperWallet) + destinationHash = newDestinationHash + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, destinationAddr, helperWallet, helperPrivKey, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + } + } + } + + var err cosmwasm.StdError + var originAddress sdk.AccAddress + var msg string + + inputCoins := CoinsToInput(stringToCoins(test.coinsToSend)) + if destinationType == "user" { + msg = fmt.Sprintf(`{"bank_msg_send":{"to":"%s","amount":%s}}`, receivingWallet.String(), inputCoins) + destinationAddr = receivingWallet + } else if destinationType == "init" { + msg = fmt.Sprintf(`{"send_multiple_funds_to_init_callback":{"code_id":%d,"coins":%s,"code_hash":"%s"}}`, destinationCodeId, inputCoins, destinationHash) + // destination address will only be known after the contract is init + } else { + msg = fmt.Sprintf(`{"send_multiple_funds_to_exec_callback":{"to":"%s","coins":%s,"code_hash":"%s"}}`, destinationAddr, inputCoins, destinationHash) + } + + var wasmEvents []ContractEvent + if originType == "init" { + _, _, originAddress, wasmEvents, err = initHelperImpl(t, keeper, ctx, originCodeId, fundingWallet, nil, fundingWalletPrivKey, msg, false, originVersion.IsCosmWasmV1, defaultGasForTests, -1, stringToCoins(test.balancesBefore)) + } else if originType == "exec" { + _, _, originAddress, _, _ = initHelper(t, keeper, ctx, originCodeId, helperWallet, helperWallet, helperPrivKey, `{"nop":{}}`, false, originVersion.IsCosmWasmV1, defaultGasForTests) + + if originVersion.IsCosmWasmV1 { + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], helperWallet) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, originAddress, helperWallet, helperPrivKey, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + } + + _, _, _, wasmEvents, _, err = execHelperMultipleCoins(t, keeper, ctx, originAddress, fundingWallet, fundingWalletPrivKey, msg, false, originVersion.IsCosmWasmV1, math.MaxUint64, stringToCoins(test.balancesBefore), -1) + } else { + // user sends directly to contract + originAddress = fundingWallet + wasmCount := int64(-1) + if !test.isSuccess { + wasmCount = 0 + } + if destinationType == "exec" { + _, _, _, _, _, err = execHelperMultipleCoins(t, keeper, ctx, destinationAddr, fundingWallet, fundingWalletPrivKey, `{"no_data":{}}`, false, destinationVersion.IsCosmWasmV1, math.MaxUint64, stringToCoins(test.coinsToSend), wasmCount) + } else { + _, _, destinationAddr, _, err = initHelperImpl(t, keeper, ctx, destinationCodeId, fundingWallet, fundingWallet, fundingWalletPrivKey, `{"nop":{}}`, false, destinationVersion.IsCosmWasmV1, math.MaxUint64, wasmCount, stringToCoins(test.coinsToSend)) + + if destinationVersion.IsCosmWasmV1 && destinationAddr != nil { + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], helperWallet) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, destinationAddr, fundingWallet, fundingWalletPrivKey, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + } + } + } + + if !test.isSuccess { + require.NotEmpty(t, err) + + expectedErrorMsg := test.errorMsg + if originType != "user" { + expectedErrorMsg = "dispatch: submessages: " + expectedErrorMsg + } + expectedErrorMsg = "encrypted: " + expectedErrorMsg + require.Equal(t, expectedErrorMsg, err.Error()) + } else { + require.Empty(t, err) + + originCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, originAddress) + require.Equal(t, test.balancesAfter, originCoinsAfter.String()) + + if destinationType == "init" && originType != "user" { + var newContractBech32 string + for _, v := range wasmEvents[1] { + if v.Key == "contract_address" { + newContractBech32 = v.Value + break + } + } + require.NotEmpty(t, newContractBech32) + + destinationAddr, _ = sdk.AccAddressFromBech32(newContractBech32) + } + + destinationCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, destinationAddr) + require.Equal(t, test.destinationBalancesAfter, destinationCoinsAfter.String()) + } + }) + } + }) + } + }) + } +} + +func TestWasmMsgStructureAfterMigrate(t *testing.T) { + for _, from := range testContracts { + t.Run(fmt.Sprintf("from %s", from.CosmWasmVersion), func(t *testing.T) { + for _, to := range testContracts { + t.Run(fmt.Sprintf("to %s", to.CosmWasmVersion), func(t *testing.T) { + for _, firstCallType := range []string{"init", "exec"} { + t.Run(fmt.Sprintf("first call %s", firstCallType), func(t *testing.T) { + for _, secondCallType := range []string{"init", "exec"} { + t.Run(fmt.Sprintf("second call %s", secondCallType), func(t *testing.T) { + for _, test := range []struct { + description string + msg string + isSuccess bool + isErrorEncrypted bool + expectedError string + }{ + { + description: "Send invalid input", + msg: `{\"blabla\":{}}`, + isSuccess: false, + isErrorEncrypted: true, + expectedError: "unknown variant", + }, + { + description: "Success", + msg: `{\"wasm_msg\":{\"ty\": \"success\"}}`, + isSuccess: true, + isErrorEncrypted: true, + expectedError: "", + }, + { + description: "StdError", + msg: `{\"wasm_msg\":{\"ty\": \"err\"}}`, + isSuccess: false, + isErrorEncrypted: true, + expectedError: "custom error", + }, + { + description: "Panic", + msg: `{\"wasm_msg\":{\"ty\": \"panic\"}}`, + isSuccess: false, + isErrorEncrypted: false, + expectedError: "panicked", + }, + } { + t.Run(test.description, func(t *testing.T) { + ctx, keeper, fromCodeID, _, walletA, privKeyA, _, _ := setupTest(t, from.WasmFilePath, sdk.NewCoins()) + + wasmCode, err := os.ReadFile(to.WasmFilePath) + require.NoError(t, err) + + toCodeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") + codeInfo, err := keeper.GetCodeInfo(ctx, toCodeID) + require.NoError(t, err) + toCodeHash := hex.EncodeToString(codeInfo.CodeHash) + require.NoError(t, err) + + toAddress := sdk.AccAddress{} + if secondCallType != "init" { + _, _, toAddress, _, err = initHelper(t, keeper, ctx, toCodeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, to.IsCosmWasmV1, defaultGasForTests) + require.Empty(t, err) + + if to.IsCosmWasmV1 && toAddress != nil { + newCodeId, newCodeHash := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + toCodeID = newCodeId + toCodeHash = newCodeHash + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, toAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + } + } + + fromAddress := sdk.AccAddress{} + if firstCallType == "init" { + _, _, _, _, err = initHelper(t, keeper, ctx, fromCodeID, walletA, walletA, privKeyA, fmt.Sprintf(`{"call_to_%s":{"code_id": %d, "addr": "%s", "code_hash": "%s", "label": "%s", "msg": "%s"}}`, secondCallType, toCodeID, toAddress, toCodeHash, "blabla", test.msg), test.isErrorEncrypted, true, defaultGasForTests) + } else if firstCallType == "exec" { + _, _, fromAddress, _, err = initHelper(t, keeper, ctx, fromCodeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, from.IsCosmWasmV1, defaultGasForTests) + require.Empty(t, err) + if from.IsCosmWasmV1 && fromAddress != nil { + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, fromAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + } + _, _, _, _, _, err = execHelper(t, keeper, ctx, fromAddress, walletA, privKeyA, fmt.Sprintf(`{"call_to_%s":{"code_id": %d, "addr": "%s", "code_hash": "%s", "label": "%s", "msg": "%s"}}`, secondCallType, toCodeID, toAddress, toCodeHash, "blabla", test.msg), test.isErrorEncrypted, true, math.MaxUint64, 0) + } + + if test.isSuccess { + require.Empty(t, err) + } else { + require.NotEmpty(t, err) + require.Contains(t, fmt.Sprintf("%+v", err), test.expectedError) + } + }) + } + }) + } + }) + } + }) + } + }) + } +} + +func TestCosmosMsgCustomAfterMigrate(t *testing.T) { + for _, callType := range []string{"init", "exec"} { + t.Run(callType, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + var err cosmwasm.StdError + var contractAddress sdk.AccAddress + + if callType == "init" { + _, _, contractAddress, _, err = initHelperImpl(t, keeper, ctx, codeID, walletA, walletA, privKeyA, fmt.Sprintf(`{"cosmos_msg_custom":{}}`), false, true, defaultGasForTests, -1, sdk.NewCoins()) + } else { + _, _, contractAddress, _, err = initHelperImpl(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, false, true, defaultGasForTests, -1, sdk.NewCoins()) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + _, _, _, _, _, err = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"cosmos_msg_custom":{}}`), false, true, math.MaxUint64, 0) + } + + require.NotEmpty(t, err) + require.Contains(t, err.Error(), "Custom variant not supported: invalid CosmosMsg from the contract") + }) + } +} + +func TestV1SendsFundsWithReplyAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + _, _, _, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"deposit_to_contract":{}}`, false, true, defaultGasForTests, 200) + require.Empty(t, err) + + _, _, _, _, _, err = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"send_funds_with_reply":{}}`, true, true, math.MaxUint64, 0) + + require.Empty(t, err) +} + +func TestV1SendsFundsWithErrorWithReplyAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + _, _, _, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"send_funds_with_error_with_reply":{}}`, false, true, math.MaxUint64, 0) + + require.NotEmpty(t, err) + require.Contains(t, fmt.Sprintf("%+v", err), "an sdk error occoured while sending a sub-message") +} + +func TestCallbackSanityAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, initEvents, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + requireEvents(t, + initEvents, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "init", Value: "🌈"}, + }, + }, + ) + + newCodeId, newCodeHash := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + _, _, data, execEvents, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"a":{"contract_addr":"%s","code_hash":"%s","x":2,"y":3}}`, contractAddress.String(), newCodeHash), true, true, defaultGasForTests, 0) + require.Empty(t, err) + + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "banana", Value: "🍌"}, + }, + { + {Key: "kiwi", Value: "🥝"}, + {Key: "contract_address", Value: contractAddress.String()}, + }, + { + {Key: "watermelon", Value: "🍉"}, + {Key: "contract_address", Value: contractAddress.String()}, + }, + }, + execEvents, + ) + + require.Equal(t, []byte{2, 3}, data) +} + +func TestCodeHashExecCallExecAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + newCodeId, newCodeHash := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, addr, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + t.Run("GoodCodeHash", func(t *testing.T) { + _, _, _, events, _, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr, newCodeHash, `{\"c\":{\"x\":1,\"y\":1}}`), true, true, defaultGasForTests, 0) + + require.Empty(t, err) + + var newContractBech32 string + for _, v := range events[1] { + if v.Key == "contract_address" { + newContractBech32 = v.Value + break + } + } + require.NotEmpty(t, newContractBech32) + + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: addr.String()}, + {Key: "b", Value: "b"}, + }, + { + {Key: "contract_address", Value: newContractBech32}, + {Key: "watermelon", Value: "🍉"}, + }, + }, + events, + ) + }) + t.Run("EmptyCodeHash", func(t *testing.T) { + _, _, _, _, _, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"","msg":"%s"}}`, addr, `{\"c\":{\"x\":1,\"y\":1}}`), false, true, defaultGasForTests, 0) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "failed to validate transaction", + ) + }) + t.Run("TooBigCodeHash", func(t *testing.T) { + _, _, _, _, _, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%sa","msg":"%s"}}`, addr, newCodeHash, `{\"c\":{\"x\":1,\"y\":1}}`), true, true, defaultGasForTests, 0) + + require.NotEmpty(t, err) + if true { + require.Contains(t, + err.Error(), + "v1_sanity_contract_v2::msg::ExecuteMsg: Expected to parse either a `true`, `false`, or a `null`.", + ) + } else { + require.Contains(t, + err.Error(), + "parsing test_contract::contract::HandleMsg: Expected to parse either a `true`, `false`, or a `null`.", + ) + } + }) + t.Run("TooSmallCodeHash", func(t *testing.T) { + _, _, _, _, _, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr, newCodeHash[0:63], `{\"c\":{\"x\":1,\"y\":1}}`), false, true, defaultGasForTests, 0) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "failed to validate transaction", + ) + }) + t.Run("IncorrectCodeHash", func(t *testing.T) { + _, _, _, _, _, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","msg":"%s"}}`, addr, `{\"c\":{\"x\":1,\"y\":1}}`), false, true, defaultGasForTests, 0) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "failed to validate transaction", + ) + }) +} + +func TestGasIsChargedForExecCallbackToExecAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, newCodeHash := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, addr, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + // exec callback to exec + _, _, _, _, _, err := execHelperCustomWasmCount(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"a":{"contract_addr":"%s","code_hash":"%s","x":1,"y":2}}`, addr, newCodeHash), true, true, defaultGasForTests, 0, 3) + require.Empty(t, err) +} + +func TestMsgSenderInCallbackAfterMigrate(t *testing.T) { + for _, testContract := range testContracts { + t.Run(testContract.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + newCodeId, newCodeHash := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, addr, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + _, _, _, events, _, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"callback_to_log_msg_sender":{"to":"%s","code_hash":"%s"}}`, addr.String(), newCodeHash), true, true, defaultGasForTests, 0) + + require.Empty(t, err) + requireEvents(t, []ContractEvent{ + { + {Key: "contract_address", Value: addr.String()}, + {Key: "hi", Value: "hey"}, + }, + { + {Key: "contract_address", Value: addr.String()}, + {Key: "msg.sender", Value: addr.String()}, + }, + }, events) + }) + } +} + +func TestDepositToContractAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, addr, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + contractCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr) + walletCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletA) + + require.Equal(t, "", contractCoinsBefore.String()) + require.Equal(t, "200000denom", walletCoinsBefore.String()) + + _, _, data, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"deposit_to_contract":{}}`, false, true, defaultGasForTests, 17) + + require.Empty(t, execErr) + + contractCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr) + walletCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletA) + + require.Equal(t, "17denom", contractCoinsAfter.String()) + require.Equal(t, "199983denom", walletCoinsAfter.String()) + + require.Equal(t, `[{"denom":"denom","amount":"17"}]`, string(data)) +} + +func TestContractSendFundsAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, addr, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + _, _, _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"deposit_to_contract":{}}`, false, true, defaultGasForTests, 17) + + require.Empty(t, execErr) + + contractCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr) + walletCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletA) + + require.Equal(t, "17denom", contractCoinsBefore.String()) + require.Equal(t, "199983denom", walletCoinsBefore.String()) + + _, _, _, _, _, execErr = execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_funds":{"from":"%s","to":"%s","denom":"%s","amount":%d}}`, addr.String(), walletA.String(), "denom", 17), false, true, defaultGasForTests, 0) + + contractCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr) + walletCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletA) + + require.Equal(t, "", contractCoinsAfter.String()) + require.Equal(t, "200000denom", walletCoinsAfter.String()) + + require.Empty(t, execErr) +} + +func TestContractSendFundsToExecCallbackAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, newCodeHash := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, addr, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + _, _, addr2, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + _, migrateErr = migrateHelper(t, keeper, ctx, newCodeId, addr2, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + contractCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr) + contract2CoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr2) + walletCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletA) + + require.Equal(t, "", contractCoinsBefore.String()) + require.Equal(t, "", contract2CoinsBefore.String()) + require.Equal(t, "200000denom", walletCoinsBefore.String()) + + _, _, _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_funds_to_exec_callback":{"to":"%s","denom":"%s","amount":%d,"code_hash":"%s"}}`, addr2.String(), "denom", 17, newCodeHash), true, true, defaultGasForTests, 17) + + require.Empty(t, execErr) + + contractCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr) + contract2CoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr2) + walletCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletA) + + require.Equal(t, "", contractCoinsAfter.String()) + require.Equal(t, "17denom", contract2CoinsAfter.String()) + require.Equal(t, "199983denom", walletCoinsAfter.String()) +} + +func TestContractSendFundsToExecCallbackNotEnoughAfterMigrate(t *testing.T) { + for _, testContract := range testContracts { + t.Run(testContract.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, newCodeHash := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, addr, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + _, _, addr2, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + _, migrateErr = migrateHelper(t, keeper, ctx, newCodeId, addr2, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + contractCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr) + contract2CoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr2) + walletCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletA) + + require.Equal(t, "", contractCoinsBefore.String()) + require.Equal(t, "", contract2CoinsBefore.String()) + require.Equal(t, "200000denom", walletCoinsBefore.String()) + + _, _, _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_funds_to_exec_callback":{"to":"%s","denom":"%s","amount":%d,"code_hash":"%s"}}`, addr2.String(), "denom", 19, newCodeHash), false, true, defaultGasForTests, 17) + + require.NotNil(t, execErr.GenericErr) + require.Contains(t, execErr.GenericErr.Msg, "insufficient funds") + + contractCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr) + contract2CoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr2) + walletCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletA) + + // The state here should have been reverted by the APP but in go-tests we create our own keeper + // so it is not reverted in this case. + require.Equal(t, "17denom", contractCoinsAfter.String()) + require.Equal(t, "", contract2CoinsAfter.String()) + require.Equal(t, "199983denom", walletCoinsAfter.String()) + }) + } +} + +func TestExecCallbackContractErrorAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + require.Equal(t, 1, len(initEvents)) + + newCodeId, newCodeHash := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + _, _, data, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"callback_contract_error":{"contract_addr":"%s","code_hash":"%s"}}`, contractAddress, newCodeHash), true, true, defaultGasForTests, 0) + + require.NotNil(t, execErr.GenericErr) + require.Contains(t, execErr.GenericErr.Msg, "la la 🤯") + // require.Empty(t, execEvents) + require.Empty(t, data) +} + +func TestExecCallbackBadParamAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + require.Equal(t, 1, len(initEvents)) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + _, _, data, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"callback_contract_bad_param":{"contract_addr":"%s"}}`, contractAddress), true, true, defaultGasForTests, 0) + + require.NotNil(t, execErr.GenericErr) + require.Contains(t, execErr.GenericErr.Msg, "v1_sanity_contract_v2::msg::ExecuteMsg") + require.Contains(t, execErr.GenericErr.Msg, "unknown variant `callback_contract_bad_param`") + require.Empty(t, data) +} + +func TestCallbackExecuteParamErrorAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, newCodeHash := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + msg := fmt.Sprintf(`{"a":{"code_hash":"%s","contract_addr":"notanaddress","x":2,"y":3}}`, newCodeHash) + + _, _, _, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, msg, false, true, defaultGasForTests, 0) + + require.Contains(t, err.Error(), "invalid address") +} + +func TestExecuteIllegalInputErrorAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + _, _, _, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `bad input`, true, true, defaultGasForTests, 0) + + require.NotNil(t, execErr.GenericErr) + require.Contains(t, execErr.GenericErr.Msg, "Error parsing") +} + +func TestExecContractErrorAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddr, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + t.Run("generic_err", func(t *testing.T) { + _, _, _, _, _, err := execHelper(t, keeper, ctx, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"generic_err"}}`, true, true, defaultGasForTests, 0) + + require.NotNil(t, err.GenericErr) + require.Contains(t, err.GenericErr.Msg, "la la 🤯") + }) + t.Run("invalid_base64", func(t *testing.T) { + _, _, _, _, _, err := execHelper(t, keeper, ctx, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"invalid_base64"}}`, true, true, defaultGasForTests, 0) + + if true { + require.NotNil(t, err.GenericErr) + require.Contains(t, err.GenericErr.Msg, "ra ra 🤯") + } else { + require.NotNil(t, err.InvalidBase64) + require.Equal(t, "ra ra 🤯", err.InvalidBase64.Msg) + } + }) + t.Run("invalid_utf8", func(t *testing.T) { + _, _, _, _, _, err := execHelper(t, keeper, ctx, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"invalid_utf8"}}`, true, true, defaultGasForTests, 0) + + if true { + require.NotNil(t, err.GenericErr) + require.Contains(t, err.GenericErr.Msg, "ka ka 🤯") + } else { + require.NotNil(t, err.InvalidUtf8) + require.Equal(t, "ka ka 🤯", err.InvalidUtf8.Msg) + } + }) + t.Run("not_found", func(t *testing.T) { + _, _, _, _, _, err := execHelper(t, keeper, ctx, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"not_found"}}`, true, true, defaultGasForTests, 0) + + if true { + require.NotNil(t, err.GenericErr) + require.Contains(t, err.GenericErr.Msg, "za za 🤯") + } else { + require.NotNil(t, err.NotFound) + require.Equal(t, "za za 🤯", err.NotFound.Kind) + } + }) + t.Run("parse_err", func(t *testing.T) { + _, _, _, _, _, err := execHelper(t, keeper, ctx, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"parse_err"}}`, true, true, defaultGasForTests, 0) + + if true { + require.NotNil(t, err.GenericErr) + require.Contains(t, err.GenericErr.Msg, "na na 🤯") + require.Contains(t, err.GenericErr.Msg, "pa pa 🤯") + } else { + require.NotNil(t, err.ParseErr) + require.Equal(t, "na na 🤯", err.ParseErr.Target) + require.Equal(t, "pa pa 🤯", err.ParseErr.Msg) + } + }) + t.Run("serialize_err", func(t *testing.T) { + _, _, _, _, _, err := execHelper(t, keeper, ctx, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"serialize_err"}}`, true, true, defaultGasForTests, 0) + + if true { + require.NotNil(t, err.GenericErr) + require.Contains(t, err.GenericErr.Msg, "ba ba 🤯") + require.Contains(t, err.GenericErr.Msg, "ga ga 🤯") + } else { + require.NotNil(t, err.SerializeErr) + require.Equal(t, "ba ba 🤯", err.SerializeErr.Source) + require.Equal(t, "ga ga 🤯", err.SerializeErr.Msg) + } + }) + t.Run("unauthorized", func(t *testing.T) { + _, _, _, _, _, err := execHelper(t, keeper, ctx, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"unauthorized"}}`, true, true, defaultGasForTests, 0) + + if true { + // Not supported in V1 + require.NotNil(t, err.GenericErr) + require.Contains(t, err.GenericErr.Msg, "catch-all 🤯") + } else { + require.NotNil(t, err.Unauthorized) + } + }) + t.Run("underflow", func(t *testing.T) { + _, _, _, _, _, err := execHelper(t, keeper, ctx, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"underflow"}}`, true, true, defaultGasForTests, 0) + + if true { + // Not supported in V1 + require.NotNil(t, err.GenericErr) + require.Contains(t, err.GenericErr.Msg, "catch-all 🤯") + } else { + require.NotNil(t, err.Underflow) + require.Equal(t, "minuend 🤯", err.Underflow.Minuend) + require.Equal(t, "subtrahend 🤯", err.Underflow.Subtrahend) + } + }) +} + +func TestExecPanicAfterMigrate(t *testing.T) { + for _, testContract := range testContracts { + t.Run(testContract.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, addr, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + _, _, _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"panic":{}}`, false, true, defaultGasForTests, 0) + + require.NotNil(t, execErr.GenericErr) + require.Contains(t, execErr.GenericErr.Msg, "the contract panicked") + }) + } +} + +func TestCanonicalizeAddressErrorsAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + require.Equal(t, 1, len(initEvents)) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + // this function should handle errors internally and return gracefully + _, _, data, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"test_canonicalize_address_errors":{}}`, true, true, defaultGasForTests, 0) + require.Empty(t, execErr) + require.Equal(t, "🤟", string(data)) +} + +func TestV1ReplyChainAllSuccessAfterMigrate(t *testing.T) { + amountOfContracts := uint64(5) + ctx, keeper, codeIds, codeHashes, walletA, privKeyA, _, _ := setupChainTest(t, TestContractPaths[v1Contract], sdk.NewCoins(), amountOfContracts) + contractAddresses := make([]sdk.AccAddress, amountOfContracts) + + for i := uint64(0); i < amountOfContracts; i++ { + _, _, contractAddresses[i], _, _ = initHelper(t, keeper, ctx, codeIds[i], walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + + newCodeId, newCodeHash := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddresses[i], walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + codeHashes[i] = newCodeHash + } + + executeDetails := make([]ExecuteDetails, amountOfContracts-1) + for i := uint64(1); i < amountOfContracts; i++ { + executeDetails[i-1] = ExecuteDetails{ + ContractAddress: contractAddresses[i].String(), + ContractHash: codeHashes[i], + ShouldError: false, + MsgId: 9000, + Data: fmt.Sprintf("%d", i), + } + } + + marshaledDetails, err := json.Marshal(executeDetails) + require.Empty(t, err) + + _, _, data, _, _, err := execHelper(t, keeper, ctx, contractAddresses[0], walletA, privKeyA, fmt.Sprintf(`{"execute_multiple_contracts":{"details": %s}}`, string(marshaledDetails)), true, true, math.MaxUint64, 0) + require.Empty(t, err) + + expectedFlow := "" + for i := uint64(amountOfContracts - 1); i > 0; i-- { + expectedFlow += contractAddresses[i].String() + " -> " + } + + expectedFlow += contractAddresses[0].String() + + require.Equal(t, expectedFlow, string(data)) +} + +func TestV1ReplyChainPartiallyRepliedAfterMigrate(t *testing.T) { + amountOfContracts := uint64(10) + amountOfContractToBeReplied := uint64(5) + + ctx, keeper, codeIds, codeHashes, walletA, privKeyA, _, _ := setupChainTest(t, TestContractPaths[v1Contract], sdk.NewCoins(), amountOfContracts) + contractAddresses := make([]sdk.AccAddress, amountOfContracts) + + for i := uint64(0); i < amountOfContracts; i++ { + _, _, contractAddresses[i], _, _ = initHelper(t, keeper, ctx, codeIds[i], walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + + newCodeId, newCodeHash := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddresses[i], walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + codeHashes[i] = newCodeHash + } + + executeDetails := make([]ExecuteDetails, amountOfContracts-1) + for i := uint64(1); i < amountOfContracts; i++ { + msgId := uint64(9000) + if i >= amountOfContractToBeReplied { + msgId = 0 + } + + executeDetails[i-1] = ExecuteDetails{ + ContractAddress: contractAddresses[i].String(), + ContractHash: codeHashes[i], + ShouldError: false, + MsgId: msgId, + Data: fmt.Sprintf("%d", i), + } + } + + marshaledDetails, err := json.Marshal(executeDetails) + require.Empty(t, err) + + _, _, data, _, _, err := execHelper(t, keeper, ctx, contractAddresses[0], walletA, privKeyA, fmt.Sprintf(`{"execute_multiple_contracts":{"details": %s}}`, string(marshaledDetails)), true, true, math.MaxUint64, 0) + require.Empty(t, err) + + expectedFlow := "" + + expectedFlow += fmt.Sprintf("%d", amountOfContractToBeReplied) + " -> " + + for i := uint64(amountOfContractToBeReplied - 2); i > 0; i-- { + expectedFlow += contractAddresses[i].String() + " -> " + } + + expectedFlow += contractAddresses[0].String() + + require.Equal(t, expectedFlow, string(data)) +} + +func TestV1ReplyChainWithErrorAfterMigrate(t *testing.T) { + amountOfContracts := uint64(5) + ctx, keeper, codeIds, codeHashes, walletA, privKeyA, _, _ := setupChainTest(t, TestContractPaths[v1Contract], sdk.NewCoins(), amountOfContracts) + contractAddresses := make([]sdk.AccAddress, amountOfContracts) + + for i := uint64(0); i < amountOfContracts; i++ { + _, _, contractAddresses[i], _, _ = initHelper(t, keeper, ctx, codeIds[i], walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + + newCodeId, newCodeHash := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddresses[i], walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + codeHashes[i] = newCodeHash + } + + executeDetails := make([]ExecuteDetails, amountOfContracts-1) + for i := uint64(1); i < amountOfContracts; i++ { + executeDetails[i-1] = ExecuteDetails{ + ContractAddress: contractAddresses[i].String(), + ContractHash: codeHashes[i], + ShouldError: false, + MsgId: 9000, + Data: fmt.Sprintf("%d", i), + } + } + + executeDetails[amountOfContracts-2].ShouldError = true + + marshaledDetails, err := json.Marshal(executeDetails) + require.Empty(t, err) + + _, _, data, _, _, err := execHelper(t, keeper, ctx, contractAddresses[0], walletA, privKeyA, fmt.Sprintf(`{"execute_multiple_contracts":{"details": %s}}`, string(marshaledDetails)), true, true, math.MaxUint64, 0) + require.Empty(t, err) + + expectedFlow := "err -> " + for i := uint64(amountOfContracts - 4); i > 0; i-- { + expectedFlow += contractAddresses[i].String() + " -> " + } + + expectedFlow += contractAddresses[0].String() + + require.Equal(t, expectedFlow, string(data)) +} + +func TestLastMsgMarkerMultipleMsgsInATxAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop": {}}`, true, true, defaultGasForTests) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + msgs := []string{`{"last_msg_marker_nop":{}}`, `{"last_msg_marker_nop":{}}`} + + results, err := execHelperMultipleMsgs(t, keeper, ctx, contractAddress, walletA, privKeyA, msgs, true, true, math.MaxUint64, 0) + require.NotEqual(t, nil, err) + require.Equal(t, 1, len(results)) +} + +func TestIBCHooksIncomingTransferAfterMigrate(t *testing.T) { + for _, test := range []struct { + name string + // remoteDenom: "port_on_other_chain/channel_on_other_chain/base_denom" (e.g. transfer/channel-0/uscrt) or base_denom (e.g. uatom) + remoteDenom string + // localDenom: denom on Secret ("denom" or "ibc/...") + localDenom string + }{ + { + name: "denom originated from Secret", + remoteDenom: "transfer/channel-0/denom", + localDenom: "denom", + }, + { + name: "denom is base denom of the other chain", + remoteDenom: "uatom", + localDenom: "ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2", + }, + } { + for _, testContract := range testContracts { + t.Run(test.name, func(t *testing.T) { + t.Run(testContract.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins(sdk.NewInt64Coin(test.localDenom, 1))) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + data := ibctransfertypes.FungibleTokenPacketData{ + Denom: test.remoteDenom, + Amount: "1", + Sender: "ignored", + Receiver: contractAddress.String(), // must be the contract address, like in the memo + Memo: fmt.Sprintf(`{"wasm":{"contract":"%s","msg":{"log_msg_sender":{}}}}`, contractAddress.String()), + } + dataBytes, err := json.Marshal(data) + require.NoError(t, err) + + sdkMsg := ibcchanneltypes.MsgRecvPacket{ + Packet: ibcchanneltypes.Packet{ + Sequence: 0, + SourcePort: "transfer", // port on the other chain + SourceChannel: "channel-0", // channel on the other chain + DestinationPort: "transfer", // port on Secret + DestinationChannel: "channel-0", // channel on Secret + Data: dataBytes, + TimeoutHeight: ibcclienttypes.Height{}, + TimeoutTimestamp: 0, + }, + ProofCommitment: []byte{}, + ProofHeight: ibcclienttypes.Height{}, + Signer: walletA.String(), + } + + ctx = PrepareSignedTx(t, keeper, ctx, walletA, privKeyA, &sdkMsg) + + _, execErr := keeper.Execute(ctx, contractAddress, walletA, []byte(`{"log_msg_sender":{}}`), sdk.NewCoins(sdk.NewInt64Coin(test.localDenom, 1)), nil, cosmwasm.HandleTypeIbcWasmHooksIncomingTransfer) + + require.Empty(t, execErr) + + events := tryDecryptWasmEvents(ctx, nil) + + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + { + Key: "msg.sender", + Value: "", + }, + }, + }, + events, + ) + }) + }) + } + } +} + +func TestIBCHooksOutgoingTransferAckAfterMigrate(t *testing.T) { + for _, test := range []struct { + name string + sdkMsgSrcPort string + sdkMsgSrcChannel string + sdkMsgDestPort string + sdkMsgDestChannel string + sdkMsgAck string + wasmInputSrcChannel string + wasmInputAck string + wasmInputCoin sdk.Coins + ics20PacketSender string + ics20PacketMemoSender string + err string + }{ + { + name: "happy path", + sdkMsgSrcPort: "transfer", + sdkMsgSrcChannel: "channel-0", + sdkMsgDestPort: "transfer", + sdkMsgDestChannel: "channel-1", + sdkMsgAck: `{"result":"AQ=="}`, + wasmInputSrcChannel: "channel-0", + wasmInputAck: "\\\"eyJyZXN1bHQiOiJBUT09In0=\\\"", + wasmInputCoin: sdk.NewCoins(), + ics20PacketSender: "", + ics20PacketMemoSender: "", + err: "", + }, + { + name: "contract address mismatch", + sdkMsgSrcPort: "transfer", + sdkMsgSrcChannel: "channel-0", + sdkMsgDestPort: "transfer", + sdkMsgDestChannel: "channel-1", + sdkMsgAck: `{"result":"AQ=="}`, + wasmInputSrcChannel: "channel-0", + wasmInputAck: "\\\"eyJyZXN1bHQiOiJBUT09In0=\\\"", + wasmInputCoin: sdk.NewCoins(), + ics20PacketSender: "secret1e8fnfznmgm67nud2uf2lrcvuy40pcdhrerph7v", + ics20PacketMemoSender: "", + err: "failed to verify transaction", + }, + { + name: "contract address mismatch 2", + sdkMsgSrcPort: "transfer", + sdkMsgSrcChannel: "channel-0", + sdkMsgDestPort: "transfer", + sdkMsgDestChannel: "channel-1", + sdkMsgAck: `{"result":"AQ=="}`, + wasmInputSrcChannel: "channel-0", + wasmInputAck: "\\\"eyJyZXN1bHQiOiJBUT09In0=\\\"", + wasmInputCoin: sdk.NewCoins(), + ics20PacketSender: "", + ics20PacketMemoSender: "secret1e8fnfznmgm67nud2uf2lrcvuy40pcdhrerph7v", + err: "failed to verify transaction", + }, + { + name: "contract address mismatch 3", + sdkMsgSrcPort: "transfer", + sdkMsgSrcChannel: "channel-0", + sdkMsgDestPort: "transfer", + sdkMsgDestChannel: "channel-1", + sdkMsgAck: `{"result":"AQ=="}`, + wasmInputSrcChannel: "channel-0", + wasmInputAck: "\\\"eyJyZXN1bHQiOiJBUT09In0=\\\"", + wasmInputCoin: sdk.NewCoins(), + ics20PacketSender: "secret19e75l25r6sa6nhdf4lggjmgpw0vmpfvsw5cnpe", + ics20PacketMemoSender: "secret1e8fnfznmgm67nud2uf2lrcvuy40pcdhrerph7v", + err: "failed to verify transaction", + }, + { + name: "channel mismatch", + sdkMsgSrcPort: "transfer", + sdkMsgSrcChannel: "channel-0", + sdkMsgDestPort: "transfer", + sdkMsgDestChannel: "channel-1", + sdkMsgAck: `{"result":"AQ=="}`, + wasmInputSrcChannel: "channel-1", + wasmInputAck: "\\\"eyJyZXN1bHQiOiJBUT09In0=\\\"", + wasmInputCoin: sdk.NewCoins(), + ics20PacketSender: "", + ics20PacketMemoSender: "", + err: "failed to verify transaction", + }, + { + name: "no coins should be sent", + sdkMsgSrcPort: "transfer", + sdkMsgSrcChannel: "channel-0", + sdkMsgDestPort: "transfer", + sdkMsgDestChannel: "channel-1", + sdkMsgAck: `{"result":"AQ=="}`, + wasmInputSrcChannel: "channel-0", + wasmInputAck: "\\\"eyJyZXN1bHQiOiJBUT09In0=\\\"", + wasmInputCoin: sdk.NewCoins(sdk.NewInt64Coin("denom", 1)), + ics20PacketSender: "", + ics20PacketMemoSender: "", + err: "failed to verify transaction", + }, + { + name: "ack mismatch", + sdkMsgSrcPort: "transfer", + sdkMsgSrcChannel: "channel-0", + sdkMsgDestPort: "transfer", + sdkMsgDestChannel: "channel-1", + sdkMsgAck: "yadayada", + wasmInputSrcChannel: "channel-0", + wasmInputAck: "\\\"eyJyZXN1bHQiOiJBUT09In0=\\\"", + wasmInputCoin: sdk.NewCoins(), + ics20PacketSender: "", + ics20PacketMemoSender: "", + err: "failed to verify transaction", + }, + } { + t.Run(test.name, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + testIcs20PacketSender := test.ics20PacketSender + if testIcs20PacketSender == "" { + testIcs20PacketSender = contractAddress.String() + } + + testIcs20PacketMemoSender := test.ics20PacketMemoSender + if testIcs20PacketMemoSender == "" { + testIcs20PacketMemoSender = contractAddress.String() + } + + data := ibctransfertypes.FungibleTokenPacketData{ + Denom: "ignored", + Amount: "1", + Sender: testIcs20PacketSender, // must be the contract address, like in the memo + Receiver: "ignored", + Memo: fmt.Sprintf(`{"ibc_callback":"%s"}`, testIcs20PacketMemoSender), + } + dataBytes, err := json.Marshal(data) + require.NoError(t, err) + + sdkMsg := ibcchanneltypes.MsgAcknowledgement{ + Packet: ibcchanneltypes.Packet{ + Sequence: 0, + SourcePort: test.sdkMsgSrcPort, // port on Secret + SourceChannel: test.sdkMsgSrcChannel, // channel on Secret + DestinationPort: test.sdkMsgDestPort, // port on the other chain + DestinationChannel: test.sdkMsgDestChannel, // channel on the other chain + Data: dataBytes, + TimeoutHeight: ibcclienttypes.Height{}, + TimeoutTimestamp: 0, + }, + Acknowledgement: []byte(test.sdkMsgAck), + ProofAcked: []byte{}, + ProofHeight: ibcclienttypes.Height{}, + Signer: walletA.String(), + } + + ctx = PrepareSignedTx(t, keeper, ctx, walletA, privKeyA, &sdkMsg) + + _, execErr := keeper.Execute(ctx, + contractAddress, + walletA, + []byte( + fmt.Sprintf(`{"ibc_lifecycle_complete":{"ibc_ack":{"channel":"%s","sequence":0,"ack":"%s","success":true}}}`, + test.wasmInputSrcChannel, + test.wasmInputAck, + )), + test.wasmInputCoin, + nil, + cosmwasm.HandleTypeIbcWasmHooksOutgoingTransferAck, + ) + + if test.err == "" { + require.Empty(t, execErr) + events := tryDecryptWasmEvents(ctx, nil) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "ibc_lifecycle_complete.ibc_ack.channel", Value: test.sdkMsgSrcChannel}, + {Key: "ibc_lifecycle_complete.ibc_ack.sequence", Value: "0"}, + {Key: "ibc_lifecycle_complete.ibc_ack.ack", Value: strings.ReplaceAll(test.wasmInputAck, "\\", "")}, + {Key: "ibc_lifecycle_complete.ibc_ack.success", Value: "true"}, + }, + }, + events, + ) + } else { + require.Contains(t, execErr.Error(), test.err) + } + }) + } +} + +func TestIBCHooksOutgoingTransferTimeoutAfterMigrate(t *testing.T) { + for _, test := range []struct { + name string + sdkMsgSrcPort string + sdkMsgSrcChannel string + sdkMsgDestPort string + sdkMsgDestChannel string + wasmInputSrcChannel string + wasmInputCoin sdk.Coins + ics20PacketSender string + ics20PacketMemoSender string + err string + }{ + { + name: "happy path", + sdkMsgSrcPort: "transfer", + sdkMsgSrcChannel: "channel-0", + sdkMsgDestPort: "transfer", + sdkMsgDestChannel: "channel-1", + wasmInputSrcChannel: "channel-0", + wasmInputCoin: sdk.NewCoins(), + err: "", + }, + { + name: "contract address mismatch", + sdkMsgSrcPort: "transfer", + sdkMsgSrcChannel: "channel-0", + sdkMsgDestPort: "transfer", + sdkMsgDestChannel: "channel-1", + wasmInputSrcChannel: "channel-0", + wasmInputCoin: sdk.NewCoins(), + ics20PacketSender: "secret1e8fnfznmgm67nud2uf2lrcvuy40pcdhrerph7v", + ics20PacketMemoSender: "", + err: "failed to verify transaction", + }, + { + name: "contract address mismatch 2", + sdkMsgSrcPort: "transfer", + sdkMsgSrcChannel: "channel-0", + sdkMsgDestPort: "transfer", + sdkMsgDestChannel: "channel-1", + wasmInputSrcChannel: "channel-0", + wasmInputCoin: sdk.NewCoins(), + ics20PacketSender: "", + ics20PacketMemoSender: "secret1e8fnfznmgm67nud2uf2lrcvuy40pcdhrerph7v", + err: "failed to verify transaction", + }, + { + name: "contract address mismatch 3", + sdkMsgSrcPort: "transfer", + sdkMsgSrcChannel: "channel-0", + sdkMsgDestPort: "transfer", + sdkMsgDestChannel: "channel-1", + wasmInputSrcChannel: "channel-0", + wasmInputCoin: sdk.NewCoins(), + ics20PacketSender: "secret19e75l25r6sa6nhdf4lggjmgpw0vmpfvsw5cnpe", + ics20PacketMemoSender: "secret1e8fnfznmgm67nud2uf2lrcvuy40pcdhrerph7v", + err: "failed to verify transaction", + }, + { + name: "channel mismatch", + sdkMsgSrcPort: "transfer", + sdkMsgSrcChannel: "channel-0", + sdkMsgDestPort: "transfer", + sdkMsgDestChannel: "channel-1", + wasmInputSrcChannel: "channel-1", + wasmInputCoin: sdk.NewCoins(), + err: "failed to verify transaction", + }, + { + name: "no coins should be sent", + sdkMsgSrcPort: "transfer", + sdkMsgSrcChannel: "channel-0", + sdkMsgDestPort: "transfer", + sdkMsgDestChannel: "channel-1", + wasmInputSrcChannel: "channel-0", + wasmInputCoin: sdk.NewCoins(sdk.NewInt64Coin("denom", 1)), + err: "failed to verify transaction", + }, + } { + t.Run(test.name, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + testIcs20PacketSender := test.ics20PacketSender + if testIcs20PacketSender == "" { + testIcs20PacketSender = contractAddress.String() + } + + testIcs20PacketMemoSender := test.ics20PacketMemoSender + if testIcs20PacketMemoSender == "" { + testIcs20PacketMemoSender = contractAddress.String() + } + + data := ibctransfertypes.FungibleTokenPacketData{ + Denom: "ignored", + Amount: "1", + Sender: testIcs20PacketSender, // must be the contract address, like in the memo + Receiver: "ignored", + Memo: fmt.Sprintf(`{"ibc_callback":"%s"}`, testIcs20PacketMemoSender), + } + dataBytes, err := json.Marshal(data) + require.NoError(t, err) + + sdkMsg := ibcchanneltypes.MsgTimeout{ + Packet: ibcchanneltypes.Packet{ + Sequence: 0, + SourcePort: test.sdkMsgSrcPort, // port on Secret + SourceChannel: test.sdkMsgSrcChannel, // channel on Secret + DestinationPort: test.sdkMsgDestPort, // port on the other chain + DestinationChannel: test.sdkMsgDestChannel, // channel on the other chain + Data: dataBytes, + TimeoutHeight: ibcclienttypes.Height{}, + TimeoutTimestamp: 0, + }, + ProofUnreceived: []byte{}, + ProofHeight: ibcclienttypes.Height{}, + Signer: walletA.String(), + } + + ctx = PrepareSignedTx(t, keeper, ctx, walletA, privKeyA, &sdkMsg) + + _, execErr := keeper.Execute(ctx, + contractAddress, + walletA, + []byte( + fmt.Sprintf(`{"ibc_lifecycle_complete":{"ibc_timeout":{"channel":"%s","sequence":0}}}`, + test.wasmInputSrcChannel, + )), + test.wasmInputCoin, + nil, + cosmwasm.HandleTypeIbcWasmHooksOutgoingTransferTimeout, + ) + + if test.err == "" { + require.Empty(t, execErr) + events := tryDecryptWasmEvents(ctx, nil) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "ibc_lifecycle_complete.ibc_timeout.channel", Value: test.sdkMsgSrcChannel}, + {Key: "ibc_lifecycle_complete.ibc_timeout.sequence", Value: "0"}, + }, + }, + events, + ) + } else { + require.Contains(t, execErr.Error(), test.err) + } + }) + } +} diff --git a/x/compute/internal/keeper/test_common.go b/x/compute/internal/keeper/test_common.go index edd4ea280..73a593928 100644 --- a/x/compute/internal/keeper/test_common.go +++ b/x/compute/internal/keeper/test_common.go @@ -109,6 +109,7 @@ const ( hackAtomContract = "hackatom.wasm" v010Contract = "contract.wasm" v1Contract = "v1-contract.wasm" + v1MigratedContract = "v1-contract-v2.wasm" plaintextLogsContract = "plaintext_logs.wasm" ibcContract = "ibc.wasm" v010WithFloats = "contract_with_floats.wasm" @@ -127,6 +128,7 @@ var TestContractPaths = map[string]string{ hackAtomContract: filepath.Join(".", contractPath, hackAtomContract), v010Contract: filepath.Join(".", contractPath, v010Contract), v1Contract: filepath.Join(".", contractPath, v1Contract), + v1MigratedContract: filepath.Join(".", contractPath, v1MigratedContract), plaintextLogsContract: filepath.Join(".", contractPath, plaintextLogsContract), ibcContract: filepath.Join(".", contractPath, ibcContract), v010WithFloats: filepath.Join(".", contractPath, v010WithFloats), diff --git a/x/compute/internal/keeper/testdata/v1-contract-v2.wasm b/x/compute/internal/keeper/testdata/v1-contract-v2.wasm new file mode 100755 index 0000000000000000000000000000000000000000..27373cab84e6096be1fd52feb1209c4615ec96ff GIT binary patch literal 1894770 zcmeFa3!G(DedoI$=bSoqPMzx0-34?*YxX&Gv^we54ugP%oAmCX5wF}&n2ev#ct6)W zG(txx5CL1S-Z)SoDn=4fNyJAC8U-977mY?VCeu;l_)Lh`i5fM7(L|!Cs9d8)%Z3ezt?~L*V@VX&v;szBuV-Y>1c23YJQTvZT;bIZoj*B zXO|tnO!iKNXUX0y7EG_!HNR8;<<--x?CDi|6Rr&IRSC^pb(J;4AO5OUp3)k>seP6A z15m1*~8_pE(aUi@p%Nv2eEQ~mhLeHYN$ zmFHdl%%@zk?>R|duV?pNc+z7Y^9zris52KIKIQ!V7hE*)s(sSf7{0M5j^^`q$vF4}j&CFec${AVNs>pfTJ?R(bwmp}c=YNY)up1JSJ=bU%JMdx39 z8DoEG`z7tPlVxc#yKb0eS*OGQiT))#?eNpf_^;RLX1b?fhZmi+MOkh#66BzK&NH~Y<{={7ESQW8t$y$kgZ>@SN79Mv#B|l zJIUJZR8Nk{I!Q|V=~OzEbUO*Kv$<~P*ltf|7E-(sb-Y8@I$4jJLXQU04I^nMY2H0{a|`TFhw`0HcjHE= z)9Y$*G!L|1XH&0p{INYC2_J$4mZ!VZ)6<*y*PEU;xB$_ue!A1y=D8^f0E2fu8%)wU zmad56JnJSP*nZTPDbbmBI-Mzco=u;ynFqk>w7Xr1F+DY%O-*m54CwcRq(Ghm0q6y4*#|DG#Pg`=U1oY;^Kj%e|1vc{r(rG`g=fs zr{0sT>pX4W)1H3ibF!p=@nz50fBt3rFBYfYlTPh>_Pz_A$>qn=wsCy&@w9#AzRNFt zPV$L#>S-50)g4{f9^BMbV@p{(I^B!~F&hsvK`epm~J$wIo7ob#t@q={hL5p3u z?-~2AeEM^e#cbz_RPeaiVr>aSgvT$4TOpmp|L zdF9iuoT%}6e{%TJnReciwsE zy7SN5ciDw`+CT5Si}sy=`FT${{~7!8Z2EP`ewp@vJN-Z3+xpG?o7rPtmVYGwm)3uL zX?jiizSg%}Z_i$u|Cj9B=~KU#eLwq`Y%#wkzcznfeqH|j`~~?7^Xu~$<-d`?IKLsk zHGN}x(Y5JwFSzR0|I<@m(mv_puciOTlmElL>3>hZk-nn+K>GFcyXilt-$}2@o|nBl zdtdhc?1R}mvj3WWF1t7TaQ5Ep&$16?AISbZ`-|+$*_X1v%s!QUGW%%u*V+G@{kQC` ztpnK~XMd2rGkaHdclJlwThaV~n7u9glk64w&G{?y*XF;QzdZlr`~&%a%|DobIR8-o z-u#RCJ^3f||CWCu|Ev6?`CsH8%fFg`Eq@^Ydj5N@-*4U0dVT9vtyi~R+4^|v!>xaA zy}k7}txvb!-TG+j#`b4h|JeFc>!s~4x9)F!rS-CQ@6Fe2e@XlGNGt~J#6^CRvbbd2 z-fEXcI-ez@PPQxCRirzT)}BF9bmp_}Xlf?y^Gw&{ZqX@Q3lw~u-WJ{AO9jQtb^Cf! zrVHb#Q!)xts^~71+fPrDevy{R=}8MPQwCwI#vH~}6UG!URBvjb98(W~QxPC_RjHV| zq{x58TAwQN;mhjw>$*k8n^!%bo*gd;Mebb!Lg+m}%Jc~iq|8zR`t7{5n{#Y0gHu55UJbh1`5@Vq3AEyORi~I>EjMK79 zvF;O27^T)lBV0Ftrp{!_~lFjiap_8X%Lv=kXb;Vyb!QF6Sc>Ogt$|9qbm>~mz zM#T*!=Cf9j3~#-TGLTodqujbwSQ|-^TT|7T*7b+Cd0_^ZH3pa0gDbLyF&$W8a6B!t z)drV02bcTc=u17gJPZyLF*p^k2A7Ay<;}tIusJy0j=&c9j)TiIxO|1dJ%|;LgL@#k zWE@84!quY6fn)(prh3pFr^CCS7g>o`c7f%*{6Mm>BS~nGCufe@BBCfS5~O8&|ENR# zAEa088EGhhD_d8NrgAG&@_3L?8omTNyjTfqyGVne>D@@&Dr`7ogM=cDqUwEYm#| zQkl60w2JYvznt2ZC3>0bC2DF5J&_!=7RFr~keY(~0`{yMG-XX^K~3>G_KCWxRAiTw zZD|<2>I4n5r0#gSOy-j}3R$NlC*fg1Ie6*2M} z`=3_iyVFziosJuR?_4Oq{Q_DVepOgzjyYExyH57(x4ik3vC<=Bm! zmYEv+VVKv?O^|EnCF9msl++>;M>kyKRxXffOIdgCPIo*tsa2!OoHR4z~(kHXz3ZwnZz*9p3X*U~KlNEb})bS^0~=@z|;F3^&?DF5uyiK~$^ zlgY_sRpe7ytqNc;5d|NqEK6WU&0@ybcumK!1#FhH&@#%(E#R?(6N)vY`zdy3X^52|fi!3v_(wi+e-x8!Ln z+Tox2xD`d+p|73nm3>^OH+)-V^WlOu3Sq0FQ1EeE2k~)V(r^QZl?Z0L%A)KJKP6K# zZsS_(?$+yEJGW#Khu?B;+mK=w{fRDutDyzI- zil$+BQ+ozjG^Qt@+h!|x&>and$y1SOBoIQbmHnCH4?gv9au8wW5C^fYKZ!8f3dnog zW2Vk{^!UOj2QRr1B~qoNYomo zt{-{!!BoC!`OnE&yqL8Yq4Mtsa0e=Iuk$B6lJ}+ZcFViG#-ZQE0K?FPzq>S?J%eL){T2qG%HBj) zj)gw}0PXvDpvRRP0d}0cj@u`J-0nb*agw~r(QmbdeQMOrgA4B77V>1X_}m?`xpAq<%3DV|tXzVO-u zi%HoYzEbn=K?b5zxoBB=gT3g77j&B!@PD=~Np^q!Z{PX*xBbB<-|}GctBf1^!cb-I zDCtY&%;C&HdNdwII*S#b+90Ii9)cJrb=Cf>;B6lB;(O_W^g({F4XZg!aYKP!+6?82 z_Mm2%@)g$E?r>!&)|P3N2FeD&K}H9$i!+;-qk|bX8U#T$2oY7UuDS}3nl8K7QL_YR zv;Cr1W@imha8^HJbfx-6Qb=jj$OlrXq&+E3T*lVytZP2og#3taG z_2vv4bKUM5!r6yV#4(yY<>f6k&(aj^ev7ykN~1c8S!RDdb%E!vTcSR~%LWtQY@jOD z@fuehH}Vvgy*VBCqv{a28$&b6Xq^P!7z-bbH!l@NGE*4#h7zkQgCLbd7yRK0f-ji> zoTlYL@Hh60ekJ(V)4k9!HGaLiwP&zi*DsyhK{>y zmdHLe>K;h;`xCN16vB{w(*aGP5Hv}@#BOG^o|e@;-IUK+K1q>g)zkK*JWmgpt$gh~q zvKH#1U2%Ww%BrOxrR8F#>Dh>(N$7P6j-~i@X_6r2HiH~3>E(bh91thx)DB%vntFPQ`qpt6v9=kJ<;|9X)WH)TorJb zs;VE*gvRnlQNcBp+R&me_<>j};TP3VWTROR&Zwc*@K&>68{oBdCyX`}>tHP|jGw(% zXANd+pbBg(B^v0P6!gO=xFe^n>GDu!^};voBD!IOdd03V$26bA+EF;o$c@>4Fo%*)Sqq0|nFa zeCGmoGD=_<<;hldQ9`i{`@;Q3;htYL?q|@V%|_p_)Vw%$kA9;``983@PLoPj>A2kB zmuD;#L%%w0p;+%%CodGUezlY6zh7-%D30?hCdiw7TC`=M82B?LB|bq?C~|Ihas4k@ zJ4CLIl>{fnWD%O%)O2HD2})1X`bM0_lwQt?Pg6oOFiw)^GQ-Z__4RYx$`)ieVQw|*}Uv~ zp8w&0_{t~V_JtL^>|-RQo9$O|Os)Ie%U&-uZ#tI}$DWHO>8n<29@54s$hX`N#eOC~+)HEcp^BL62{qnOi=7jO3=>>91DKb%eOY*a~6*bBv}R zO>8l=V+BH!1}W-4u%Wev2LZtl%nz_p$<3BGybRgq-dgCu0Y{vz09frhqKr+j&lTum zwmuHI2 z{;062Bqb{TmKaB0Hz0t1%HScNbGtEm@;@q01|!?#_072%JsMQ_J@qwq0$*h%Dl`Pi z6^FSaW{iV36vq+$!Df#ub`QWei;vb}kvB#($iX}TGjtoOY3{bs@x=+Zf%h$Ujy4q= zM+41`D>;oKu|_$aR#m)mSv0u^IC@3jE{mB{(1ExZEY3WrDMCQ{2_SuwSrCg*2;)YJ zz8T8U!_7t{Q>H9I8cxhFgEY1f@2pTU>2mBqxwZOZ+3=wLnDj~T$4p>h&CN4}q!o3H zqJaJ5!H$Fwk^ZoL$=ui7F%lzHAYMR5a9OO+)|{$Dh)0+hlbad0ToN zACb_5{#5?_3jRYAPd;&Hi7UDgYFh<%B$r$NO`iS16(-SNwUyG^dyoNamG6DofyIPX zirdU-H(_&ap%7lrH43Y7u@wh+k+;wd8slPvU&j=2QR`;zwaS&3a-mRNev*f@wU-rk z3tBQ?g;91SPXh2B>GvJU|Bj1{B5?O)<8rrzDdIt$k1e2*-Zq>MJz!@uAVv#_C@_C%iwCB*uxrt zHbpIjab2QRqp8?(3W!umUNbJuE~C!Ho1f>U)S_ms%v0e>sl4ORb(l5%8E68ct9&o@!eBCs|=)nrp`Q1z9TQd&Ff?J{vvs(3tu+l&OnTG{jRyH&8+;C#0^# zwJ67oJcw4!QqhOA(byP6G&qbhQ;@1-<|QgjhGtX!)NM;*RB+o81}w~gUK;|om-#$E zEatf4EPSO1h`Fvy=ken4d*utMw|*%a!C)FGw2&M?%m;&&e;{Q_OJc@7FP246!VpD= zuM;C<^YQ4DP>J=Zg|H@ff10Lo8Mm2EWq{FX@*cFdLw4I-$ZpGbBX{DEn{T8YEtut{ zR{gl#P6f?iPss|q>T)&D6J9+;dJIgZM)-vQ3_pDx;81OANhlF&c6w&YoESSKsGJt^ zNPt+UksQfr-~F#{wBN}lmgqy0qcX38%}z&oocn_RjPwPwe;B46Nr-hb!=<=eT;(Tn zSaszOX-8)Ga^=t26%LBlbW@u|=glSD6jSCa z)H&iP`D)W}T*5U9!$&KjW8X)IYj#atZAft2`<-< z@?6p==PXxbNUL_AWhqvFwIn-5)d`L;II21=Qdj=B(5oa>nF&LABL6K@yeGPC6!v%z zJhUST(VoY#0#Uc%E?Q(d?mWD!mXyf}2Lv9R&(0C|&1Yv1XZ0s+oSE2-DWU5myF>W-mmw21VdtK8T2S>f?3h_*b zg6;gHthSvJ^4y=JtuV?HwzGgQhcD22y$Lci6cT>ucVmp(az(Mt)N2N_{`BOLaOi1f zc7wyld8pFyeXH3c*i8x8Rj&HPf~lfc{x zxi+{|ek19BHT7!cuIfw(K$be>YM$0=>}>{Fk$zd4CN<*e90^}g2@iV~|Ds*dNgGop zP#TBdhB|`g71d(Xq=l9OY1F95lkI8{sCDP=-c{p{qICE?o!cxA)nP7x@Ttf1Go<?S&wB$SUTZj-nxwa!wKuvI4c6MK`wLAnJ~!)*UT*L_S{J1dS$mRh94G zk``Pcm;9r{bX~;S#MA{&H6+CRI@5GJ7b>UM#8-WFZNfC8WwTd*&JeqPq`L3EnmS2HO_pZb#zag3J5EF z)~EG~q(&L{NMoFIz+D%O24b=cg(l*Uo?Y|gk@~^?lgx)5%@+Mp1&cR*STIu}9T_e? z&D|-k|5!8E!!!x0H8bU(UwdFNDZ`TA2_uW5D79v${IIYT}-W^J=@GNWuCOtwE`OhZ}*w+qd}Hm@Jppy;B+8ZajnaDa6CP z0c0G*A%PTYi6hpDVoUHaz%`@iVoWs=;m5_b&`)(a^ph^nXHWL-KFKLDklVThi-We1 zIA!_)z|=<<41Zt#jS*8Viqw{Qve$E7o=mc@rC6vZktS>Ii7z&(tu!v~Sxbr(dO+Ua zRjD=?!b?p)BNk#@rZ`6=RTx9p5@x#^XS}q4;OgiR&O>Fig94fQV@o;_wj*G&521)- z49ygMboC4?Wcf-J_pCq_nzWp$2LFf-o|mHya57(W3!_vD#x_KZEk2d9JPsF*L%f;P zgRmnBUy$uYDI&mDqRjk^^?O*tUJo!ijy-a)+1V3V)sRwkzL9bAucY&Y)~X~G(n~^; z3f>*Na%DGheM7nmYR@xViY^uuYPZCHGoujKoM1yRZS)Hv>*=Bw!kU(D*7IpD4cH7J z%q6Qx`Pt&%vlMX6%a7Lz1pi-J!?@=hq;X0G<->VR*LhRUh6_)ar6_}XJSGkCQf^K7e`$t`Kqxh0b5@=$3HwbyiHfbwXXk?YOrG3DMYfw= zI(xZOG@)I&G#!V3w!0OmA4Sn=#0 zT9yyQs~IXQ@{^+wcmef!IHgHdyXrD3J9fl7vCBKrVx?GIM9|6|`6(VuOVRkO?XwJB zskeGaZ-{4v;W!jUG|V##m4GvuN@exxZs7B^Ys8(50kx10*xNbI9ZwE;-T^Z>{D4lt z(>4%I{@fL#fkwR>nc?p`{tfxJzD7_a^h$rhm5|r*WU5X`rW)v>Ib5BY<28DF07sKd zr6=s}im|i;3+O!+)(X0_XRt|^qmd=LI{a4jvqbZjd0K|XzNf>ZhZ;cKb<-{bz)a+Y zbSyilYFnJ0$Ivc`0m{Dwch40b=d))!AF?%Ckl=Ai%$~akFU$Fz<;@7zT_WRsX~rQXzUNAEosV;){%8yMoNzx=%ta%oB#k8tS@G7 zWBAA1HX80u$z7HPF|ujpZUPnJz#1K%$xWQ^26BQ!CU;ieWa;a{wtDaKkh}#{c-@8t zQwTO%GjNWiBXW)WZ?D;|+%eS^4b>th4 zG!E<-Y0$t1EG0k5M_0wS@lLj7`%i^B4#OGGy&PaWOPiY$iDnXfqm#sF0TXUCc8DC0 z{ziq#zp*8T#8}^yljYa=>}~y>yNeeT!#l4dKWm*`Z{%8P(}sAVrUn-ICHL*cF;>1; z22~SM@X%$N*WRy_L-0SeAc~7PtB{KwhG6TGan zyPJI_#o`2768C<{574An#!VVK9llY48$G<-7sNAjdIBEhjbaZX^SOKK0a}acXnYbr z^&R(pAg4dcB{4eNW6WZSAh^>X^lx5CDQ|H4i5kf1PtEBk0;NM-aQX>obdhO-NWtk> znBVq>9%N)DbGeqfj9}3inu^o5iWLFelOXChnDR69dL&rJ_yG z5ius}wKg|&?ggFo_+|Nh#zP1VN`ed_!N#3~#tI|mQAHy(VEhH+heJFfzxViNrBFO)C50LMoE0ymwa0nJ&aoX5)-#5Gpbq%z z=CY2af!} zqEc3CENXe%pz&xh;f;pn2__`sDjcsF`btb_EXc0BlprDFs>u6i*4%WNl^?RJe3B2> zO5TsEvUA~YFIHTP#}QhB3-2-b(ln6^AA$o8i2zkgq;SMBrR8V6&B(H$L21#olXi^^ zUJq|V5^XtqjcjBy$YqpC$}ia{+GNL?;2p*&1bIzjx_lIe*;-BauUYRmET{XSkfDJZ zSm~N;o!g3qVa;vk;I0wV=91#7nA*R|I@lS$F*5EZVtqF0Un4Z!069JfQ7T(JI13(${ZdI39NsD}#Ia_yC{!z7-V@gr`+t{ba-UA55T)uPiRcL6X&y0a z9E#R%o<@desU>tj%T1jr+R+_ql|*gibL8sDL`FD19 zAZ~2NxgTmOVFDS|T-WChEt@|yClB2)d0-M8r6o=t6p1E~!tXa3XJ@tWNGmQfopc4U zHsBL(TMhef40e}!iJh+)AWK+jf=0;7 zLeLCW4$Z(5&Ei>4u(d(c4LXlZ;*+^xgeE5a@aveR&Ur51c40!DK#KEPiouqx0d3W) zkwDRNDXHP@(cVf1{Uw_FWa%91>zEUz6kVrpt!8hvl|tH!V-W4|SDVRt*Qu*YMeCAs z>Iq(xx%Nhc`9M15 zx1KNc4T#1;pMlLo=W{kLJaJ)chg!|hDwE3VW5!*V9fG!YMZ{|dsvO}*Oj#Km68e`y19V)JkZv(*)J)c$%QeLXDO&>rIbN%sUr$X2DIF>`0z>EsPU8!y(He>!Bcf0$ri@ zBzo#Q1jYP^*%k{mxkZN#I%o#tJRi9t#D`3==jE$xZqS&GqtsjU{h^7l46xLD>?d-v zSB?fMDyoTBm~@dyRleS?q;RS@3$3P7_>!m7lP5>ruhn6%Z>zNBtyZ%K^a~q-9x78c zSSl8C<1!M(E?*el7_~6P6cAEC7G?wRj^xQ9BE+VfrQJ-+*M@F3!a;z5mmjj5VQt8} zY3+m2N|UVCgI?ic&QTYTxS;^FaJ2eMRv}h@$>d=5m$vF~FX+h2i7BG1u_NKCWicKQ zH*M$`Sw5LG1Iagv+TR>EOw#0=|rsX^AinW1>@v=_zkZk%Mhe7*W zv|)4jI}J(cP4u)L@)FEMxpDCfLl$1Dumz)@nSfP|dO|X_R8nK+gVwXQW9BAx>mdc` zpfd7MVz9c5kY%^}OAN#6FNwsi{?bB!E_ydO{X9AYK3O=@u}z2w4h0=&%`c=F^_QrH zgEmh}9+kJ`w&2<{5mIZ8c3@>rj4D+Z!Vxs?Z1jkHnV+#P-Ar|T1nK{?%=P)s^M+me3~ zyJ|u)%XsDdyg<{p==@9{q4Q&o6Br=3hXXK!PRNIUr1`p|+SFgM&izOe7c>m}flH)` zso@&!%MT5SVOBPnoR!r`-2IIY{n_V#=WCyM$5+FwjFLwOXYP6xv(Yh($SZ%-=GSt( zZn3M*@EwLuoA|mliAB=#6Rvqf5nD=`ERvP4barFb^!sa@srl3LG>74i?;x?}om`$c7lPUAQ+Dv`)l9f~h?dK#`r zG%h=d0y0A%zNu+bJWgL6RQYVRcsW^W+Ug|BdU7KOk!gsghz>UhVOV@f{bzCbqZmT4 z4>M?9A3w}sR;La>kfqFr8SWQL=)(*;B3<*J2lT*ahg3akF@-HlVhR?G9uFpB3i9(w zH<6&@h+9CR<%|ynECH>Jg55+!L7(7JE~F)4z@G{lbaQ!*DBut@V2WveXdO`|b1kTM zy&EC7mdj>g51%_v1`S%}UC!!EW}49}`WfA?b9AYmYL8#!Ly`LJR+C**^^!HJOiPLq zr;s{|9UQk;VpoMk4q`0#`+`jHB58O>a!xHwmk%UF11Ku+1qY;=6xphgypon9Z$gar z4yGcPuQ_}bjFiPXEb^9VH;PBV4lDR&k&l72H<7D6M!;H4g9ZDh1i@h@v%IkE7vA$% zFYbte#p*;(poFI91}3dyA?ai+M7Cb-z&X|QoFc{v>bmBuMyP0=OjnYn2YtsKNKG99K&RH6^1tZX^4SfWCUfrbr~wS{Zr zGE)eeNyCci6esr)Dl(ghyOr@bb83FM$J6a8X*?`Zl-e9Ob&UShwR1-24iu2HKXJ+rZ90S*wk+{xDRj3o#d@|{|6dgKr4Ny|YUv2Dah ze)*~SVhUaG)$X(NMm`6{RI*x!!wo<(tU^hO-c~FlU$1%X#5x>XM{|EcPi!?vO*huz zVtiBY$bv46b7QdBBH12x$`u|@%UezLO{~SK+w8VJZ1}dg;NZpL8l{P05GsS7t`T|? z*RrIz6ux9wHV6|5E!HXg&#%e#G@W+D_c_{2*VEdK#X6~#!>p^C)n3#O_OfohPO2oc zKp^XD*u0yD&)1nP(-uj_Z#It)Db&={m)!ijD^`xF7*8}wAzhC>sTw-pV38`9W<`Hv zaSKK6rAm3L6%1Li1`MWiXET^f|QkjKVe1L3{H6&Pxj~H~m+$TSwv-A^Y z9i9pcc4p>jwu7AZ&X8m52=~=FUGq7+366_j5wmj0lLBKC97kYX1C^rI83l?s z&ZJFQa&`<<$?3xl!^=XA&A_+ojDd#)V2!}oXMnoE*kXu7W^B_t@Sn}3#awYFy@db9 zJu&uQ3AtiyMJP0r{*)eQCT&$K#*R=AovWRaEkem*PV^Q{`~rX2{N9saxrxj`{VIvQWTggWeDk-6C^>nm5T{EY1*i8eTUBA=TB>6ARPN~GE4 z9-g#A!-CTUFieHV+8mmdp9@S_M9|BxST@Zzo>170I77wNvm%9JNN#^(_SdHRk(Q3JgJ>vdE2u!sR(B%4#Mgz_ zidn;}8`_W|Gns7AL^7i|2#P(GniiGJvk`Udm2w>##3!X@=@4nYS7NoBz)d8tlDg@V z=$a30zN<^G6fQ!6N=bwLQtnc%TvN$guwN7n_KT~P?3cAeA8h_5TcFx*ze2lo@%g{0 zA#J6VC6u!wllIFVP1-MeG-ljJ`z`U??7V~E$Z>2O56#zAyOlKfbL*X+S0b^bgV$?5 z_YokNbC$yp*}L`Vm+)do*4pEjT zyc@n%H8sk6Qc!K2LI~vJHT%ecfw%F-jTQZvp<4_VvA&4Y@@9LYam@KA>Oup;K3|PD zkCwifDzXvL5sEGy)Qycn(aS>~RP3wH$-9R^sP`NlVxxD4GUj)wat!>Tnjt+j+a+51 zxu0$S>?4obeh5Gh&ze;&tHEzDJp4T={o&gp{;p4P?b!w%K4GL1@%VJ`+^oZDfYnli zaj&f=st&x}JT3>IVP7*Va=!VN5Qnx8lW*CHePY!tZfIo$I?rJb3uau#a~yOmW<0q}$#fdUw;d*jL{y z!t*|pl27_)BSZ5h!!&OMlmc7Q{5_R?^g_Z$NWE*Ma#-`e(LD~K`cjE#WwBsk?%)`x zq`y9Qz@;~Qx2_gY`=W=8Kz+;#JZ2lrbpW0|+UIQNr|{~aUyg0H=M5>XmBt(DkdG@F zp?k79j_x5~BGD7M(S5Mxy4@%Vp&V*NvDTU^eVIm<`6F@W2%@$PZAJCM!cSD4T&!wC z?~#2G?@TE48}#%pSLmklpTAt8-|SWj(grI9Askk)QcZ<^cT=H@VwLyewn+^6@l=~R z&`q*vek4|k4G8k$r;^2?3R9*^+4e3eY>jNZAD|25{|d+AN&CJTaX2nHTuNfWiHz?y zW~L+t(4)@&wKz_0p64aR%ygipm|iHPMgN`}Sr0mO0U%g&kYdX^FSj_w)-dkZ2}@2p z&S+932$0VWTU1zM44dBTL9zB^0bBcp8(HZFC|0coy}N~HI;oT6U7<4wW(U1qFU@*+ ztKFIEPP0%T50MvYZkik4qz`Vn!Rd?$1!EdRD5#j7ttt7r1dW0y^G3O;W;t$ZfRp7q z&2rqVR<7MF$IWWxauh&2s%4vI*{Sj)9}{mN7~NMChpS`#&f;`u+Q| zgCF-_2^J|Es2;5qDSP9g5BfKOvz;>*z=aERmI^d-GL2G;-l1;@;@K(xMO*8wnU>CS zxsYj$H@JUcVF8}<`X-CzrNbMpLA%%q9)4oGc3&BU{NNDKVG|J0e}2L^D?j3VlZ8gM zgVqV)1r(+hTf@QOswBlH$^LEB2m4@`yrj?4Is-&OJX)6W5Fp8=F zns*s=oAmAEj>+PrJv@_#!5r@5GFZdsT2;=ivctl8zLP6WO0l;521;cKfgf-stZmEp z>S(1fzoE1b&5`MI#rf=HsS)~SzP-_j3Q>34QjWT56V~~-q~Kk*`6?|ormHFn(rlm; zv(moViEQl>0y-Nb3CzS+=6T}>*c>EhH#8$>mL;G~5C1n*675I-rMU8YRR z587dsTYRK`SY??u7G~(D$&TTSd9ieOTFcHsd@eF`g7*6DAC{enq@OeuSO+neX-e4* zl+_Ybf!ZbOXZSL+0lt*VK4QCd11c1RirNlA;_tsnYisvLC6qcUOl(2+APBn;0W z;WDNEgKquF7VU=49bJ$DowK6y);ApVHjGWmo1#&9&zbV(tui6S<;!D&Ls#A$PNlj~ zNW7JoMWq%Zc+=jCu)H{SQt;2=VNl;^a~ah48K%8XLwWf}AAs#S8uyu=0m`cC`=W;6 zQ`!gDlzgR}R{DD}6%%4;YbJDQP)ALH@2nNLo|ys%D-8v%$2M>tPbhFht&Lqn`yR!N zeim%JlqW%fU&Lil;Ptq%RXhf?j~fJVdtWtfdsQp&#b%gMdqNV%b8r=of&t?8idJ^o ztFc2vg@>U{sBrS`G#vUeNlA?;sBn!asPHw9Xt@es4CAm!qjT3%B~Jf_4JA&NVNHlo zR%omVaT<44gfE9gJU-((allcU3u{K^{3W!rwXY z0ovc6;PGD_ODz487ZZp zfA|XMT~a`rPD=BTxF|8z+1Sdkokp0`*dc|xTCs@y2QaAMEOWlq6}4I z?K`B5g~ z`)F_FOezwiPY&4xJgjGcKZR&WQ4|_Qr0RP=`jU)Qu}^$~vA6`1fnILvPcwP16w&ZS z6bo*wAN!%%t9+HonohchKVhyd_R?u60gce#9m(W`+xL3K@KaD5+G@g+CG@dZw#Mx9bMzc^9 zhY(K)A9eYkDV`8>O)YY=#AcW~eH7veuWtCQ`dr4rC(hAy$OIm>2{h+l*tP zUTNln^SylL0w|u>xim5oI}+jvGI3fx)2&C%zv>4iS^1b&;SL25%J=HCjBKE|O)I5p z$G)JcuW48w4!@VrYc87bBJQ&pOEony=a^~9k8_579mA*R7Eox+u@@DbFm$dy$!7Ie z>qsKfHohKUlWYY^6|7N&)K{o~L~iY&jKjMp1Fa=&-*lxYsRqn&B7GXptcCq5PVhiv zg9GHmt?pRXZXsnNaLsa;%uC;78IKbVp?jg;E!tQ`6mAr;$W?2EQ&tWmHIeirqdTBa zVY4Xp;Z1%s#wwEJQSLB>6HyIElRT^x6<Xcc*=8lZf>lFhAzeI^Gnj$A#z2GL*L%1rA z!){T=^4G(%oria`%7Lzt@qJ~$X1lUo9HJUY9=>RhIZ<))fs^qIU5_8$puRq=2`Tbr z)K^L~)Q3;a4jA>bCiP({y1g>>Z9Cr>9EkcXIEeb$ZpCl!fvN<`eM6D2H`KHjnwHWY zbt*<6Lsp|(f#(048G>N9p)|Z{{8zK6xN3LL`AajMO40S-)1-zns7;gwoX*#8l{aEX#_ALT7qsIIH2e7ASENMmnFsCFw{o>XX|h9x z@E`>tSC~MujUGlQ)J-zIA?bW z222)U$Dq=*Eyy(FQb{;e`e*2DV?KH+J~Or1apoYur=c#t&_q#%B&m-gHv`g<`l=Dc z*Aa;oaKJ`wJW%cyXKEW_vnFC|4J5PT>aQJ)PHQ=0r;Y@%jyY2$;Bg6>8|#_1emN|x zTGoU#Q_P>>YHB6S$`nQg^_Q)5=4#XQS};VnyY(eK>o3hdJ8lSiIKllV2&#PldKD;7oUYc-mCYBDO{mx6Kw)40~$C!NEeI zyAe}G7i(Y6Jx%McGSO7HlSUWUCMb0pS^Kg zdgt!Bt8N<`Xpx{5vw@pBe5p=es&*^2Uk{^~xMqKdiHvD&j~?6<|U$!pK1 z;ILUV)e4@CypIfjhW@J0D|j}1Bx}O6vCYAXXToUFv%w5DJR7vCc{cKzU^x0;c{Xwu zgkLSA3EAe^@UZFG=yoN~CSSp`xji-8eyGNnq29Ne0dA6ODf*X^XDRuXlDA=UznrFR zlXsj3IRqncqk+PV60VM^K9f5r&X!~;zHxR*k(b)Yb|DK1i29ZN^`jWF@KhC zIHV+#p_CPxLD@W@{bG_QzT6N_e8LZwJefe~7>HV(Yr<~xNV7LVF9~|0{WlX1^byHK zQR|gjk@Y{S$wZip4lfzETxGl79DdFAz4_SUaBSkPURA@f6ZoU8L7g{;(>UYdhc_I3 z|HAv-|Db3G(l+r~7xfs8ZP5XX6xjJowx^09!C%CAQlTJ$k;JAyHI|k;yi0WsIw{Qk zmJv&K1~PME-8hZ29tuIh5GkN_NT^(RzX$7v@myCFkOWx_+$V3x$&USjQd7i}k=( zs8!X6LXX0z5ARbEPJ+DrJ;T3_DQe(fG?<`+QNoT%blQQXam(U7=TyWbl3Cs^Xxdwz z4DVT7T$BnGDLn_BtF!GaB35|M5heZb9fI*fuPAw#r(eMf^ulwmOnDjg*nPhD)cmyO z%lMHBmX{l3HhHF?@dJ21hwg;KhT^0g?Xvb$wCo!e95!U9AWARAQxM}}LsA?}H@G!s zeDGs$f3ux}Xk}qB0+_;xGxcE}na`B$P=+pqo?Q2@GxhtQ|W&Moa*IaNMkS zEu|ZlI6j&(^8yt-pe+szQXc7!tOmL-mGY$rXo_I^)`>4@ty*mbSHwd3PPM}*(aX{64@^U?h2Wj>z4H2Q*0aemF@z}Mcqp1$kqzFb-?AMn5 z^+lH9{YDdXoD(%K|K13?4)O=BVf2g|yG3XsVIL zG=)}N#wM|Kq3wROz~l9@mSOlVc2XeUC}a3{qIx+DdM8aiLPJl^7+?t}Lv+x+_|l zg{!~1JHIge*dlCf5JWX;(yCniE=0=ld#-VvB+(R`U`r=T>7Eg&YyvJSSK_rylbU4F z&_tS&lb*``hwz%pyJeLQ_?zKO{J{=Yr7iO00B&s#`7@s(ow z-~3{uxwDF7MJvjf>Xp~qCQ}LH#7;pQ-?dYu;S^EWyKCWFXsqk8j$p4mV$J~!Hq6Sg zcbq5khzVb_P%5s*i1^`^X*@+#!O+GjqO7AfVQ>U9hlH=aSM6G1sej zh`F_2*VVi#tQ~3zjKQ}S9-Y{sIabSis4@9q3SgS>>20)ROJK$WM6HM{86pf-m?8|n z6!aXrb|^ik?e>yyE8*H-D3O+hf#=4#CIPkv?{WSjhd&hZvS59ytg;N>IB|>=0f+Wh z1alETSfuKhHjJdgB6r!%Z``cwu}*!cNX1bc0nJv9Q@`zS4nlbviCJ^fx0aBK6GMPd z9r)U*$n9+bBaqm%BdeMwzShGKZoid7Io?~AEG8^MpXSpp=| z#)=qi6y;ImQ5_U1_*;3L5O#MKx(XS|6`mTZrPr!dWv!@t1mVltUD#&l#<87^yIl%+^BE(C{m+%OkC9 zsuC#Nfx^t}jQFEe%9m2Uj8V4tYf;a?K0)+a$yXqjeXH(raoO|c^wf?!LhD%CA~5LA zVSMG-m9>u{Enl-JmeoA0@&KD-kTZ7B&+Oe|^)(fV6X{sJV%I0xWEMbAR*1#SW8Xt8 zx*lucwX!#DKKtmwGAqY%JUo$kU`aK&1~Va8X6!0_p@}=q>9zRvZ0FbTdWtfYFKDaS z6o|oJCX30}uZZDUEJQm5Z5M|8n30ZP);HbuE{wbW!4dnQ z4RIN^V8`R4zhFTCn}WZOHU+$b>mNc>LoRtZ>3AvfTD8wiwT$C62%gcF!&Jl+K_Xstqnr1?dI|W$qdUj zR)uE$%ilOK_S9Vd*%e*>me#0^o=H6TnE61p-csIGC0pLy%lftLn>g?~*gkV9l^Yei$}RLX@bH!NOT`j9~1eB3>%gFWPK?YtBj7lyfzPP=kSP;u2~{BRZ1F}qQSiIgjy}jcH!=UUqMCATS8z(2e?Hq4gVJXjVlW{%x;7Q&*&I6FeA!_v728`n74J>m zLXj0KM_qa**y&mC#(hLly0k@_jB9l3AL%RBr(V#dypElvt|}G1OUk~2j(Rl{wBC}s z;~51VU-;j_y@HN915V2IC3+y`YE>Nt4XCC|^(yMpB~asZz>3&(z$x8075|IT%mWre zon6P4o&CiUFIO*Y3D%b!tl)Bn_=Y}>MTSa_zFWdMin#1Vn&1Sn-FN!5;pGGKJi@z za+$2FQh0PNIEJW3`W+=2CE8#$*RV~^7<6o+V8|hAMoV3{V93_-pwf)?)HLJ3H6yB$ zJe?{S()@0Y=aZu%8k+Imcy?|7kMq2Bb$(T~()~bEWhYU^v&&js8G*26=%W@|k3Y#s z$@Z*#gyWoZGrjhN{I|DhYl*ptIP-fY|9L!OBrh8Wp=vGgLXM7sMJV`0-=NObx$$cO zjec7T!g~Z2%p|!5oYa46zLyskN`fB$U$rluv4*3_bIppi9S16mGfi)$?!1zn`Y`t6 zX?M)@u0&cwcCGDzV0==*;lMzB4ordbe-d^zD@o=1 z8Ls8~S!OnbU*y9Ay2E>r4R?#LG$kYk6=%E@j$_CaY*gOi&<>fbdovHqNPP(Pvdgj9 z8=SGERpt?MJ31#L7%L3p_if9z^8qg87~=X7k9MaRZzxg2oTsdXW>3bFxCcTgDn>?) zv=twz1HMgdcia=JG17|}_d-(2HzW)V>O>;HnKm z>XJoIC4tbU2J_7F;U~Slb)h4ibt54C`u;|{pKEqB9xArQAC7$pPE{uRe&U!85)UKT zSu-VFjoierGf>uW=HY!9WO&{4=>ZC(;pxt=w#u|KO2Xkc_iYj8P@6m7QX5@xJQFvw zT-(DtCS4mG5V5f1%tWStMq<#@;WyPkWFZ|sXjdr()8W79T4z6U{X8KoT>ply`&ZP+ zCu&-01Q8weBfgP$&9CSl>5-#inRZ4 z144|S>8;cvoGo=uhuzKdj8b|W4)9)`zJEwx_*nC7BS~!p}Q5kw?Ya*=z_#+ zSr;vfUaDMS5b_PxqnZ2obgKG!^VOu-V);Y8zAA<;SzS5_fMzbHYSp=z3YS=GAxz?x zD5B3^<@qk)1>fEKBCQ+EmjpAeH-L+Qq5N-NZRR|S9Rl^VIV|GU@ejtaOSn7$%wNM^;;%Y&210DDqkVvq#)_ zk@6>%C;RWttMuCpkr9!YDVA3+%=VIYyPdY%8Hee@@U`lYOIuNzo0@v-oJT7qQ}e_M zbPi$*FJSkA2%_@2sR4QM0m=CA-}Ah#a1hSE?SV(yA@ z6Bt+g?SkST;#?+I>-zl{J$woEoQ6M)-^LfS7oT*}Nh$xDKUwoe*Lh37?F8mte`YYN zyOY+PG+e)7V^9(&xT&Bvc`(w37R_VAx6M&pxC+gV(G@M=7jBvWts8+Dk7_o|O|zU)_fT1X zN3&sWngE*(Z*MltO|#r#HT?6QsuKnwX$jxfywlvFevs$?m zn&r4@mdg$Y)yD&{LNzx>3~+N3AU8)0&~ucey3y*~95KM-nmy#^hyfnk1jx-113ab) zkeg)yJ)xDmlfpA*662jTt#qNK(?J-5#5QjLYTiMSQSgdg+33X}{PFgn6 zufj<*xU^#br3wy(0HzS$2z(x`cojk2zR|Lwu+4TTB(_4l>cy*dDJ2Xwb10!vFf=m} z@m#$tckZ59DG1sBhcxZ1f*&0x_c5JHiNFpbc#V1n5^$a88abf}Nu_ zn(a}AIerbLMvXWg3|BoKv4syjP|VQ1Tu}ON9aKV>A!sZA=V8l-CF|;+G|Shu+UxXz zIKq?b2D8Rqm8q21>$(Mv$HaQYuvKk3Dbvbi{+Z%CD;c941Sof{0=UFoGhI;egLHvoahWc#g4Li^&_OOM z$QxI-uylu;$~oqyrph6Bfrr(y+{LQp!*v%At7Z9>Rm)5KN?sXyg9dURz%h8#G!Vxl zxfA77U4sUysG8Hiicz>}lIus+b=vWcqmhE4Ok@iDR&U*vG4cONMrPVXCO1D0WEumn zjSmis*QEw3UgxGc#{Q1D*zRl|EL=t0iQ@hKO)1NJnpFgEqcOc$L(ag#+}MNU49vt; z$A&JGd5$hs|FR!xr~1E4?%2 z;Wpy01)vqIK#Keha;28Hntw&hn&rAlFd?4clIB1pF%^3(mzbz6t5P}B-PC$ydSFGT zn8H01dhl>=l-T4D1OZOjaZ23g&sj`S_+l>>Y+-wn zl)KIzuyvF-XALqnXfMVcUXgKn_5Vtpjt*e|2W_m#Y*fA(k`ymz2s?iWeL9my3%JB-F4i-geTvn;T??FH;wcQC~7i zDfT}4uH7f}Q};Swu*@v4WpSwMoRn>qYd!u1omdBxER4v`8)Y+za_=GANJtEyB-DpW z0~QToXGdgq0N?WL%kpa5_*;Mk5eMkW@H+~b=MtbF zd=?I~jl^@s3>!~?(G?p*kyElQ^2phPR(|BSgr+}nG!=j=KQr+JRwOt2R|aXZo~zMD zYl<%OIT@W?xe@TY3W6F&O?fha`K-}?L8CI{MHL|TR;9?>Ki=N7(G;)*3 z?;mEP;Y`{<$;oI*rROWFSC1@3($d1KN0uUKdExemD&$M53Lo|vrBq{6Lj3q?#>TZw z`(fX3CwR8qvgHfZnNzZJpq6bNuw6LTT08=3XFRlCT?k(R)F>ODK=nNY41}hrYbx6$ zgOTxE36 z&-~>pD0JoNiDZG;-LuMjbvI*ooo7|A2W5_`vMs%ILq~E44;&eQ5P8^9qj%vuL-3a6 z!m86bG&w!&_i3~_h^-v3HqmN+;6*#OcB|@j90r>hquXw_%oxj0$ICA% zQYmJ-0~USnqNyNuu^4LUr5%i$#%=t{uD0{Sowb|;LHz!jH7ApD8S4)%FZW57wPigW zqw-}3kw+bY!qqsrq_9(qr8gU!iO{bIv5IPI8E;;ttm5NMiEDFa!e~x6_p)&oJz0-- zcWY26$!;zd^&J4|elnc-1%slJ_gYoswd^pGrwy23n!NzmbqDQLcZIKDe@C6_|NDT9 zfCtHy9g#n71w3F@Dm-ZX+8tm-<`9iWGt#;d59iomREk98N%qddiSx$Zs6~ThdCF2Y z^&z+P+S$JUSV!vO;*eC{&s;;FZA*sV*N9zQY@*f_-zfp7g;X3?Ut2CD_I6G>20q*6 z2P^4z(5=T)4JUtE9NxDDXeZ8}Iv`w827N{*Dr zaRG3Ld%h=JOnE$)Qz+`=*){B#*RCxVRX?;#Qr}G`ZI;6^P-WNwF{XA7j(Ryz6^7)) z$2=R}CGugkl$0B8(jCe65r#qAL)hHKE4H6`IUGExXFJ`YR9kK2vcE z$lf0|`@datIZ+^!^q>~AWcTHOA>+eO8|UV->JEikrlU<}Wq2i5jT3#0g^%K?o->Das^`p) z;Z)CW9lftTAgLWms!8VZZ=T@MXp@KQVX30(vnM-$4CDT0N<=+)A+`O0j z;r=oFTJVok(AjH2F`b9b4Cn_x_~k2#^eky3-YbmPHl<`K`kDN=deofpxnFK1dfLbD z8`FddY_+qm+^$3Z)=O@R-`%fZmooH`YtmW^yrSWqE^_`#+Y8Vz=22hRK@Q}Z(`md& zGnvvsOjXMlN+*kU?cHoEoTJeFHy+TFA(x1oF40($sWbS4X*`WTs?C;FyV57OciL5# zt9jm0$j zZ`%ym){b*SJ@4@#1BUvq(bj-v+<;k>4=yd04{v`SZAXQsZFfVce~kRd3<~2){$~|H zU8QxQ_~}c^@aaoCZsApIH&_Q58b7(z6fS{(2oyDEH}+Le>9(PNKF#{VOy*?=Xr<*} zPJ>+=9YL+7)MZ;_su{1%P1ue&SM3+orxC*7)r7H&O_wH{IABf0kF&)Fh&Zejq>Trh zJY?hSuMc`zb8M^vPOvmKPB&PM{M-NXRN9NwQ79(cY90bbbdJRe;=6~pM1pJgK5<|GatV%unS z+U#4^Kd>8`^yc)5Rco$e2N1w*qb|y&oQkK%8GOKM^1m^B5k%-~58ol-)$q>rQSQ=F zIecFXPlG?F`C_b#&8R=q?dw}~Heu%Nb_T_tdE5~rMm~I_i-}bo=Z=45%_qyCEeN6v zuCtR20#Ga7;&@KI0jG8>qDB3@u-CEh41>0Kvb-QAdf*g|65*7ZHpd8oUE>Yy9g}K~ zQC-TA>;aa+g+dW~21FV>tpnx4)L%e+m4UIUDUD{ki#i@zI((7*3m>?hN3>IXD;JQy z5OqKYc5xPa8Z^NLdJmr~_+++)VZb|)d}57MSR{~PG$eioGImR)YVH!g4D8a>#EnP8 zCNKl!mdNk5@6~4n#WhACdM7-DPRd!1o67>ie1Dk`214ZP<~71Xc1+t4210}m$1tDv zP&!NnyWRk(aVtO)C=EUBYc8gSK~SJRIAW^Tj2OH>!#zFG1iaKaDPcMw&rSd#q$T&HH+i{C-Wim-Lz+>REsrMeiGm{2B~zx$M{;G~13V==ms{9Hz{7_Ct)14D_B_lL zn0WwD-LG)U)%@}tfPz79%TIHQ7LdyJ_FNWIV-gEh5BN>iU2 zG3R9rQpMZ3mf28nnqBe8JeqLMLdy``=0#`3krh78;vmMxK7HwJjJ~GD>KtttLrFQp zZ25>IXAmqq-O49Pin!8m1*-kK1kg!yElxGCD=F159nv=g;E`&sq^TDDXz33}Giw6G z6i{NLE@;DWG#$0;L*tz|0eW>>v)E(=%KS2hDN%jX3m`T}oP6s#*nlU}EcPWj;KLm^ zSdjN#y*%FBII7%gRq{p^xjKqUS(Wd}V;XuDn11*e2M61-8E2DP-x~8rU24p4o>q(%=86@b2@BkzQ7I}|arl#stv@LahoOaF*qa$9 zzu>%zvAO1uA$!y0>|Fw-FX@_w;A-b;oE?0%C7kU{B9mYvU@HDrN#!J~f22j~T~HbF z4=R-bAE2$xF%yc^mmQVu=W+!5NJe!$5=<&Bz!erex6)R_zmh)XhIy*|K89K3#4ux* zr}@^vL0N%Q1#uwebYLkCpCVrCXZw zDrV4x;Gb~MeJtzM53f4w#p{MK?&yY)wvYMOfa1=#qN|ppAYK9U`2Y&8~sM?Oq!wf?{UCUXgWjJ{~_nRn zp@QAmY70of1)G5+{OM{bxWG88ImGpfh_p&}iz2J)3|Oy6JKyKn~Bm)96n0U!Sdw`q7;~LYhNnF@V$Drl3n{&R~f}4PPl- zh(5Z_{Zxwmf5cg&DG1amXeF9aGia@DAA9?TQXJK}nWcJhZKm5+^ zYPPy>G2FC#oeq{Or(6p5431OxyN{Ep$jbk;FuP;AV?S;GQ~l0$l~uQX(Nb8t{J25f z6y!=MUF@oV$LQt#_HsVF?CE7sFX!~~?t9gjp9wD|PK!gm+^CnYwU@`oj*<&dzTk5z zA0ENml%G@i4J!W$EC1*KOjugnpqK0Q@+N!Pi@;{&d^mzldJM^*f6rS!f9oBee9MT-%Aop`u9VWj$^bzq}+V4zIg#j#!*slI4&v8M7|+^UyGs_$COQK;Eb%}3~^ z(dE^DC!(DgUbgjeUN6@Rv1$3IdR^lPhA%(Vd_*LO8r!{wE`Ls!gpAYjubbrvUKqU3 zPd*g92bzzZv?m21z}u-y7Ut6O`xE7iy-wE4S?}p@eSTR_-`afS40)Q@P)|?MB?%Sq zrXgq;Y1;-Mowcnj45JBzh!aaWrnt+`HeWdOGX#-*#zl%;JQve?zO*mh~k4C&`~cv9|Fi+@UBx^&KI! z(w)JtxYwTc1B0*XR~RTeYDY9%0xI|ylc0VK{>A+^mZRZcOhAGs#C-oc{fpOJv)J@6 z?DogyU%coM>4rGlKQjMfWxI0po??Way)ZkI4$c3NbCR3?@xp(Q46TdG>T$@zo0^Yw z1VHIp<80Hrlm5@YBT&GsOlDX1k$+SCXN{(PP;{tpBmQUB zUJ(Q~ReR=>JYFVONuybL<-+XxwtG&&ugWs_pFU@mkBR+1(;9i)sH?hWvZ;L$wfn8f zpAJegEq}*q2OGO*@NaqaEj_9YAl~|jgNauj9?x6u_bt==<`=sAbf%V;RA7lq@=JXk z>ii7D8tOeOpS3Xih-|W(tzN4&+scL>=x$b+w~eAtZh5%&A6nvr50Lv9D+B z6CU4SMnpD$>zCAmK8!o*d`fM*iThtPzO3Bpyz=%hie0xxa%0|jb=GKufbeg9(I2SW z8mhY69Oiml93H8yN#C@sw#>EqMNw(Of8I0L$)iuH)tVl4+NqC zTo7u!NmYm{s#8%Wcq`^nK1z@+#b(C(!JRRtZp3-wVqJ^d2DNU42lgZ4COT=Wl9mKW zsg;fOG->&;jcSVz*pXvi<)bv@ciGGJ5gQMuzS>iLYm*}1Y!+$wm^;*%crP|KOW`kC z;hE5wsW$UMx2tefP@|#ntyXw0HvTYM4op>YjJO17us)@tiXV*WcQLFSjtij;S?HOzqXv=0v%P$E~&0Jb0`NrfU z3r5b6=l)B~HBV{)x`n40%=|9OQEHm00HwCm-1iX`Pq;%gI-^*)j8DL`fS=%FnTg zfQr%O-*Jhq*5&89+@Kx~9Lnb>p=@k){%e!3=Jaa4*ShvA6N5NLud;H=Rrw8iS$prt z^0NL<;eU;F$&?+vWc5>C**v?hpTW(uaE+{2EBGDX2)xN7J&s1|@`c%My4ilR&BnM7 z)?DX>mdz12%^WA5l+Bc2PXrzYI!|ix+XiFa;MrvGk#_k3d;AEy{*Yb&tX+S^uD9Ct zU)c4Dc72askL~(nc8%`<`2U~1H-WA*P0s@FX02DUyw_e=>gsM+ce!0QNeViUa0{v{ z?44%c6G%wnBr|l=ftdk1GO1+bOby6G4alSdGHDW->CBO#$&qs!jvN|B4h4~+0Gadz zIdn2|Xo3uN=E&)u<$0d>TmQT0$|cFNqtYqs>c9X0{onF_@B6&#_qIMa^!eZD^RxQA zqR+?)!9D*@pTRir`3w5|ls^BQJ{uNW)#oR4{pa=Brr?YE{Ftu)qCUeGg?85T`M5s+ zl0L&af$Lw=XBZ>!`Iq$>wg-G(*Jsj>|M65VgGSu2N)1(g_j2>E=7hq%{APYhd)X1= z-^srM7#bX@Q?tkGeaC1@y31ph! zqYM((xQsKV?n^1Bo7dT;Olr&grR0*UX&*t#xbH9NwFAk__!(;V8-&gn2h2of>!Cpc zyU4MEo9SC%rQlc2jBz{vD&>Vg_{-V0l)yzuNb}nuA8LIE%&731dTaFX1NvOM#pk}$OnzA`dmMyuQ`IK(#ouG)an5TB>@*|yC8qR+Nv-q2^;Gk;B=ZPU!?v+bI{ zq0hE$-qdH?H-A%~ZR5=9v)Q};wm$c|PcS|O2>~Q)N&;38{Wy+MuxgUO{B&wvgm;1q zR%wpdmXj&7IpRrClylUG>Po&QqMS{zInj=TD{tq|iFVvB{*U=rDeZhY z|4Ovu2>-9$&4@#I!pZzk=U)wTY%0bB%_RRyxWYBKoPRaKr`-JgT>h2tMVPGrz?qDb zbr6%go?nvD-hrmfs*9q1e9IA=T3KGBL>K;WTltsr4nWjs&X3?-ul*Ok-p#q0EB>V@ z$Yk7S^x0(G|E|x*)8_Trc-r67XX9y~)n}7&KcUYi;}-PUWZX~cv+az}>9g&Of27a0 zGZyvPcE(TXv+az}>$B~Qf2z;6GnVw(cE(TZv+azx^x1aCztCsc3a}%W^*I=q-_$Jp zQfUj;W#jX6YNwm^Sl%PE9@Av(tcFG7@m_UD{>|K6s6QW+xp20Y1$*`Ajs&U06F5FR zQXZ*~@V~**NZ-gv|IkQfWTd7mBO}$30nn5K%uVO^GCPYF4a8SK5=MgZ2k6Nk{BpXF zhDc-b8%SvU^IzeY&ZWdK+=3h#8RY%)7Rm?m%evoz0dro7jEtsb-V;pvhrG{YLe*$7 zzXfQ#-2A)Qmk0O;`8PoH<>n8i{M)=pvWJ1H3$7^BQw7arG5Kp*v+^s+Rs|dh4N$WX z+(?}7m-_R|I9oiGJIsdK{o>#vYr zoB^zJaEBU$6UN1N6rHZl4U;$a0NgOE8qIdNVX~G$0GqpE{=xciUlqZ#{oh;p)FJ%; zo=N;yYObD5a}SnIhaf4hOEBzX=`_N@C|mLQ#%V=>RT-hjaJDZic(A14?pdV0n6J>s zdgD*fcBMIemJR={@53v{eu$hD(i)9TpXDad%?R!GH~;(@gfE>c{q?gGa&01z?{w*Z zJv&kT+VbidYb%D2uw_IOAt-PBKtmmTxJ-Z(o>3!tJO zYNO{W-+AskzWv+&)VF@ipZpWw{7rxSkNwd<@`wM>AN&Kq|M&gg-}Ada_KhF?UBB~p z{Py4WTYt+py!w$>e)Dg7x%nHv{_B3jum9Q)|GHoM(${?TSN)o^XI?!0p;Iq>@B`1E zeE<92``mjb#v9K*^Yl|sKJoZtCypOGdgSn-v4f*fGlm8S`uh&l=yyW5-e9*TKlO2S z`c3pplz{Vz&RV<~*`tf`frmU2fRBMAH8*OXK;U2fza^zI3fP5WB7dC|^P-6VyPKo- z=NSdNeHrnr-;Fzca?MFT7LsdTKm$q65JSV5pF+H0u2@8HLA^co(3kL&j3 zv&`46G^bGT03o}`*=;U?xbbo5Wl(n&Dp>yG;%tX47<1Ug@#>IN#qsvnKS@+}gm7`0%iqKib`dKw!2iLq}hXryEA&I8^ZE^2cCm z5bMGkgm?T9*(OJG;AI39@djI@aKqo=4emKmoP942MdpJCp2xUe0^Qa>!5Orv2=T@? z*a;VI-0gH^aImQt$-6``n9d)z7oWss?o+^!N)sCb|4zT?(kb-%>eP#Ry%rF}hDWp4 zPw}Kr9RWDdu%nVo2;jy_XNM@`^>3ZE*V_83;`@)WpJiz=3`vx>?->9$%kMHC+^LPer)EYSG*#A9-6bfwk@b_alK)aFL z-@u{XuC0)cZY`ZeofmwwC@!Z4loS6_b>7Jz?DZd|EHmOvIpd@{f`>8lh<9bkt(N?a zvoBRA`80Yu_Mb#Unt$Gpcu^iwKH>VxOBm%aFS+3?gC%f^LRJZ~i*N}eL~O5(kbh%@ zeSQY`H%16zb{Qx32!>V<;n-e}OMp#=(`dd;#vvG8QfDUz3RVZ?RRf7l>}hp-SY&zGJRQ9){+wh0-!5v0C*e zB-GfsqOOPGS#-hLvp^}(hDFRjj~;T2fYL++*xscka=Yk?#-MG%oFL)0HOPWoHW632 zLp%`!K07}8GTgc#ZtN|~p@sj9jFpk+_yv)~@cMJmaX@AOU145w4sU<)iA6#%c}lA; z5uo)>-gn*LSy{M@Q(HFfjmYcf5QH=oCv6|R(a_l6AR6P7z+z>{@haq8jS*vh5whDS z>SKB!c1#csj{`Q8UDI{rC*%d#8sa6OG)iQw17I4i12pJmVjvRY$esGLiVja?xN!!C zjf2gZlt)H4^YI}s4*VEWK4CAZG#4;|b(?1nWPwv<^L*_zrd`qL2-C!5)G&igqmZ>t za?$2VW5#;bgJ_&rn?ay|_O$TD9Im4G^QR~JeP}%2IOi4zsTp*po(W^KKZ%*&l{9i_W`l zvx~FrG*7$0=ga6Wp@OCgoH!)zAbJuz@-PH`jbWdlg}jkzYh(=1qM3^#K6{!}geT(b z2`Kxc%%62K|4k?BXGA}u3`K>5t`6IZLBJ!(4uLv|sl^OC(i_&r63TQpKh-Ru=U)*B za8Z0u;_ZY0%}-gR^?&{8fAYWm+qZu9>MxYO5nl-vQS>W=t4s*yi;1Je-6xyRd=FCw z>sY|*$N6GNvq4sVJ@8SGQCP(0_t5}=;+gcR8fnr*sI0RmH)645jrjiNZ42ag_%P1?@Z$qMO!KDh08`I{aQ z@#Uhb)|a2Gq!egxX4mT`;Zr6?{^k}oop;aAxT^JRRble7IR}393)r1l+*;yIwiD=7 z!3v8Rg`7WbwHe!Z;@p>P+i|Cs8>3>6hZ>_l1}5Y9S+k5e9UUg?V<$(mPU8BoU1z<$ zNRnIwP0nHd#%~>hbcR)EH_Ubksw_X&fw2 z4_GFi4UpDTo#5`5&PcW6E7t6z2z zxm${o2wOi&qDd{jlSC&glc%Xgvd6D+C=&x8E`1iblC}GUPB%UjxV$mtjSt~A$O8%| zO8--(dmoahc2emGhQy5zse~#nl1j(CR6^xIMk*Y{!^bz5P{x_lf7{6{)Gs8|gUn*& z+8}y`00a|b$mI{xYCVpFH?rUB9LXyqPxJF#jDZ}U!9W#i4xc^KBEZ-_vrkQkJuM-I zpoU6wrM2x9Yx_x?vs)h$8ge(1kfaVs|1nwF0i|ty_`Lxo(2I!6 z10^sL34f0cgPi1jp33}^A5tA_l&M z)K>98X8YjntI7J_PS@9)BxDyFeW_G}Ne0%S6DWX+PtToe9I{U^S{<}cPn~NVwokBI zjoBwu_#L!Qum-VsDxO6~@*U=j z1E*OB);<+opmi`-Q;KyLkZ=p<3>QYey6@)3TZ&YJo|Z8ZP|cE~8t5vAEESfv&K;~JT{|O3#MzMuf^HzHn=YL% zZ6uJDE}dZ_R-{p&^Zge3-R`E2E*(U@Fn-vZQ=pLhHyA{zj~r#XbX}Oq)-2rN89Omo zSAPZ`KVk^R<{;z3OU@KpYCPU}!g1lp$%UT?To`KHW?mhMU1*@7tm$@M9dzNaEnw0G zn`W2}Q94ixZd_YTCrD(5s|#jOgGp8KdboDU*7#@P-!EZL@r#7Urqx8)MsIuw7FjIj z^oQiP#1`7X7J7N$rRqAj(iH97w~5BPcv|s&s*y2&?qTvaVpN9g)~CPJ|+E#(GfO#cr^B9T}=d? ze*F~XBzy1SALFcbfnw;+_rGELxuq=K>Z&5=m>BzZMFWT|3%elYCSdL z)MY)3SuS!wupsVT8+O7=Q&%ayplpUlt)(zo6GiR)?VVbc6Y-$OqDPLY3Kxd8$HJUU2U_G9GV756ea4#l21 z_kUFj)i>7iBC!x7!Jzgrx&g?;)`3(VmsQ@x16Wf~w<8FfK)%FNgMSIHS!Ja%Q%P+R zDo8y^^mV?Ap(XJZfpUBgXzu_8(h9*AJq`J{ggJvX5h34ni14=cFOby6T1PC+0C#}@ zB~EjQ!$1taMNTY8k)FEa+`|2^GI`GouAShuLyZ&ZwIjHMY)}&YLFo4GZe7ACo(3=Y z@s}Gv(0Jy@DGxL!o~j_z4x6wBt+22u$r3WvYJOFqEf^Kfuq1sDsSE}2BlVk*qc`(# zx)1$qk{gR@Ce30&d`4ipn|e9Bx zZm1fS@+0;MsT;o~$1X*w#pD0ENQ zvwT{*ywUdZX(5Z|vcH3`#!KJkOYyqp(_Fb_bhr@ranp5r+0e;|4g{+-{}phiv9&Anr>gyG&1xVu9?A5CbF2s6_?Y zHz8uizEOOTeUn5$u{DJWfd*p)l)|zQgM`|)KDYje+*EU>jnUSHzpg~1TQr?Kuwbn3?G}vnsm{Szf0299L5r}x86<&SO~5OI z7zTVoRezx0SrB7TD%BH3fVNd3c>`nRbg3s<1F9J zqzLFBva3|ahZSfL@28jBDk4@0i1aATbM~lEMal!4Qw-U6ej9tAV+o9TG&c|X!=OYV zW^Oh)?W`)P$ba$-BOnoq2owqOWHSoRvzTp`L}mFtSpmO`jV*x91|l}XU2w{u{dFzZ z!OL7UZ$hp#=k<87V0>0`wK<2Y=?1a}8^EoElfikVS2CBygP*ER$Q|<6t$I z^UTcI*_20HEc%+5@^}Sc&71OO(H++jzIxWW0mzM*Ep&qqTg+D7tI05PNl9k0WgRdC zn#>!Swnl0;Nf(`tY<3Dg5nqoH;q}3k_qj8a&L=AiXU4GrCo7*t#06Wye4Qb2(!K_7 za;1SBP5gs#`S>QxypjimI~UKu(I@l&{{=(QH02y$l*QD}pF#YE(-l8wK_0YREhO*8yJa`g8g97yNZq z92UJdITXpi8PSys*5N|UWJGz%=9|{m7T#)-*NHk8=*nwBY`Z{LUJF9r1-kN@KMBBg zkd3(|(3R4YI}80SDVEg-x}t?V&=mp7rI^TrsR(z}6}WBG5%dzH1HWwjA$GiIfw$_nv4*!$sNlc`9qfXM>87r5mxl~XpA%%ZdP>nY|O2W5>0hmiM^IBGcMJ&{B5ME|j z-vo4s6av7RkGSY8@O$LJAU8^q{pO&r5SC+6Roq)D{T z%6QO;Imq#pS-KLQ6Q0%7_NI-_}w#jM?9d(wJOyWnk=E25chpHIN+c<0hU+8F4w{<)gWTEut}|f2uXvR(z%!zkzuKK&6d!MYffRhSG{;2ALR7tST^} z)Y1et*iY&{-3#23#uJ?MWjRUw8>1L(SYy&n@YY#%|5C|ZVi3&vAx45gN#q6H=1Ka2aZAbE0| z%d!huTi{fUMr$} zUMr$}UTZ=5+m_DOoQd4j3(QNB63}c+ehkZoP#dQcT_y*`@z{Qb3meu41^_006<87A zI1;{8V9^kd7_B0%11A=jsXf~Xh_2$%Um&udXwA|sV?iM(tIco1*(UzjJEp4Q%r7PO z@L;$BpV(vMDdU5Mml|WT9qOiUXN(o!!D*RJ>BVSd+GY>(pJL9gUGyT~)Ny{1m@KB$ zNRa$fLGr)OrY8D7TzZ>f1Cabm=$wozXRS}VH!?8XKRHQVKm`2(5!4_o6?D^z3N}6%Fbk2u#s{Sz0gfQB;)5O) z(BuLZ{q~Cy74&&42-T0i5G=s>HXjzVmN&g-O}n_JJ0DEd6?Ra;G!Y;WlqQMmuw=+@ z3&RK&S%wj5pfF7+iWX)OhAklN5b_>}*c_;hj*eE4af21GX#zsx^)iZ5m!PsTm92mq zl2o=no_+Jq&y_#oa@bS~%WVwc3Qy`u4%-M8A>^=OuOXvbeqCGT=AB<4K*2FYE}US| zv}ocjXLKR$7K|>OTZQ|L*|r@jY+F|b%(kskVg|9bL+{#d+aqDy9-(uuFa>n+ph^+C z!ugjOaV+2-%(3PgYoK@y7^j4Lum(d+pYoH2AP^FYI%H(-NADfmZpa+H8?qJ^4QWy5 zv8W7!5+?x_WH1N@43{*2qH)L}kP{RihwzUHPi;Akpd6jC^JlmyARUqn+m1_cvXYXO zy_xIgvD+59P5RelbZMX7Qo$8SML7D%waru}Gq?K-0&*~ZSEnlqesX^=hU?D42G9bN zuQb2dO$B!oW{Y8Q3!Hn7(Goh6>1SV@nNME)Roqmka8B)bu#c=H_+^v+C{-)O; zhIsN~xbV6zG~5c|_-@5 z83!+5uLr$qA>}%rid~@u?29g$HV8!05aOiFHGy<|j6D+qL5kr(<;amE zwIfIRj-bQ-2OxxBm8#WhxmvA264aXK{}Q2rPbREjAC-X1MF!bs`)L&zEDB%!iqGAj4fd_jb5h zHh;Tf*o4F2qfAg4FdD<9FeeV9B`6FSEwOU}qbXv`-y6XVfSfSef9QtMf)kdgtQ$rn zwMLAltZ{q`M%t5q! zA4m;F`w-28i!CyzeTcRX(IB%+srcB3Xsr?>N`LjC?(LVXeK(zH-ta^xc_X7se)+u85E=2oNTjQwcsyRSA1AsHFXsq33n!-5C z4$yb^ETJv_r|<3{{y*gHJ@&gA>_7SSc7H+pq9x6eu;p3%2>dbLmuDGngRrLQ#57%2 z;V_=vO`8vJ^q>k-B26zk)0Qz{ADLu9F<=DC$!xNO6RL+`xZDEpAt`dkcf}W}#5+<~ zAF~%>Pl#>XG%m7T;&ill-Jv%`4JF;7_R`+BCwmCA9`D=33uIZ7LzD+t+A=hdx-#~+ znNnr)OezhE*XWX~HI0c3He<5AGb30nWS*ZH#fe$0X$~@?>C3HZ8OOy@vtaO&T;&J3 z4oc2-YT;kGM|0e0(S^r3$o*NTN(hgo1hG-c*E^^ZMwwtURc>GBV_&V0W*gL-&a zAWRo#3Z=R%NtP=Rdc+R`Y}#^|O01r)HC)OOSS^#)%K3 zNHCtg4X1s_p#L^LK~J%+zg+sCa7+IW+|q*%$w8z2No2l?L2l|JmywmM6%9mdHC2US+f?cGZ#RP_R*^Kq}~@#SUo-0%sW$ zpm6Jz5d@o7c`Q>(%AWPH8`uY3(J*eM4R*Ax@3n31gfMC?S!+Ht(dr_2yy{NR~$r^_Wm@8$*T z3Nx%AVcpg{iEYf76yXkq&B*PY_5snz&hRPAXwm^%KdT=u4dPdepW1n+!J3^pbO`(x z=fFYBg4F0k3VHoo+1L5VJ#E{9ND_4DJ=RydV(mFK5@P1&q-${XKEtLa1`9EBvvJAE zC}4nfZ;bH!vX?$J?W5_;kxh-mJF;tZNrO~c+n%zvot5;0 z!`VKV5l=<*kG;|XZlmqCp>%X)Ba{yR4mbY-j}JR|uzK*|0aQ!qJ6S3<|Lec};UDV% z2(YpK`cJ=zzg`^~h5Is2C>-5<5KeCRy6NZcYyPl6l6Plg4lp5Ag2>n=;`A|hDzck4 z9SZFB1q^7#dW!{iJB8_?!0v%DRJG?01Hk8xc@eOg%8g?v!{bRSyr95QxQ)qk%rVC` zagft%Dm65z+~YA6N2!0;IV>}R8%TRVJT-EK2{|vy{3I7gKLTolhEhh$2=N-k3;@EO zP_eBO=8JW#?$esSSR2T3T6Qdfo5fy{6tiaL?yDKf(i1=aa{W_3#(>|E2F@RE)?7t> zOlxs*6-7uMN7Az>!oN&yjpUX@5f&qrhWMJ|8Y`9%Wh$7%VQb)-{tuZz^TX#%xZw{+ zS9(xNun?JA@c%eL1)@i?d z-8wB_Zrdp{RUJI2AtkqR`>aZt^~*r&&?0 z0mM<7BpA4FNig<`u;(Em(?hg&9SUq1fH1OQvKuQP3j+w>daN{Mk-At zA)ZSTFa&j&7UiW~1c!obzlHE?>kct;eabJ#&+7yhVBR2KRp=noE2aVsf<#1IBlndQWPk|OCF0Wk)tBBkKU>#aq zK}nJ*+yXX=UE%;>gGHEz2lsA7_1xr0_Do){*S|Wbc@?xqwEUD4*a;iEm`)^ol%`GhFln?M7 z9<7bk>cePMmcdC{29dmpf&nDqgOwTvS|ykQ%r zM31%$LL9Al&`aWXz&k7uhF(W)Q%=D_3J3$iXwDngx7Zx%oT^OPREIdd&3cBWn5R4d zIq9R&6xP-rEDT$1oGm+5^qg{-99Uqt3bj*spb@9tX-Z*k3UZB4dcDpjfH*wy9RPbK zz60R!1V00ZC+HeDTtxy6c_Tu!yO$xs^U=%TqgnrbHyrM!&6eGiW)6eW+iPf+i5LvBK~z?%v;R*R&9+@zvp+ajF#Cgga!~-zVu^OT z?7?NUo9pZa+HE^obxYaF48XVP$qceOz`MDr)gjxQ{dkNw1&4L zatOExc<1s3w;7vDW{lzxf%Tgs@-ZQDY1A{ZQQOWDksvyOo|tlAHhWz`Rx~;at5ctOmt5Rv|mY42o~9U`Gj-x4b#v@}haVh|BGudyG1m z_JPam!$X6V4ct&Y;Bu@ZI9 zmKMWy9vIN(U<9;h#peUio+WPzK>PBZ0@}dRox_s<3?-l2L>`oM2HG7r(I!CqbvZ55x>oS)g;9|S&+ z3&ss-U4pNoEk2))$O=o#lO@1YPn9k@d_HaHYLDP^qH=I8hWX%A{ZEi?rXtHFwqWO{ z0wj$1{6bfJKB-0mK7Y;d`Nm1%^T`4}-#BR|`H0W&o!oJo`L^NnbquP-V!rN%L@$Hk z^Sc<*CKmGqpRdM7Z7WB7z8ad2`26-sIWV?rF%NX@fghK<)nbmT`}lkxpDSo_AD?4C zx`33ttV1~sYyn4&wqpgP{GX2!KIdSB&)2}Gk^)?7D$ z&;Rs3KHtaZh+N&r=iBS<2{;C5doz5#5|LGk&uBwEcLOO951>futcbSjm>bc8R$6e-aDtDN>{4sKuxpWzgyUg+J2&Aq- z=g`)}j=WOjF548ZU9!HM~@hIV}lshtBz{ zxagD=evv zn%W4QXNL0arHg+RIms0)fh(r{g}=l+fI&MUOcUseY5T}XpHXZJj%a%kRkvc={c!&v zPG^W+aZx%7_;$ud-*6!qpbm;@&3==e15p}fIQUse`*0}q!&o2R`K>i2|16UodsqxjiuTc z7&+3e&NqX*Qs2Ly)-LV0YhII~+*rnccC2lEtZ~F;1+#1}Qn?jNKo4pNR_@Es6hS(_ z2BYs6!?7-Ml53#MTj2nAtOv@HA?=V;cI*Kel1=ki%#Pm1c>oOBd>&L*L{1juEF{?l zo8&AcxelA;EEFqn7hE;BdV)CI3%yt1PD81-UV(cR@4{U4RD?SYM!CZrj6lwm1X~ED znlgr5#=e0}ys)Pr4h|gc3~~M&60qZ*o)_H*%fmkCgp|IEZkj>24~7{{3Zg~4hth}B zcx(}>zVaEyF|&X+etqSmL}HA3!X!dI1aFSTxsQZuXsY0!R72CV#+>e}I5!w*za7iD z@xDyrW5_aq-+Ld#3n*gaeL_w&gi|=;Yt>8Q2Nuk7b#BmHjlq~n92qY0JQqSPtJqDx zjBamx+iW3ixy%9YR95$}*dv!<9z~9da;2hszRd0Ua(ILw4x! zrZMC_VqOOT?2Hb-d&kk?cmAqChl{z8_UQ1sLx+n7Z5|19_(w=G3z7b1sR6=SurX%n z@LE@NIIl(mI{d7m!#P|fx-X!^IoEtdhgY_O4qq;fAHb@-OZ%ZWkO2?3joDBVV`52s zhA>YTt%8Uh&i71ezMIV{hgfmexXDxee0g)M__Pk^dz#BK-P+i+HTI-I_=^Rsh^O9- zCGlxa1ZrjsGas>k@I>E<%843_SjQh{OROSouv9A}8KBnusqd%R&=)Oa;$WFs0<~b0 zGZ@0eL1$>Zp(hRmLnDa*wS-_##8cjQrKhMnNtZ&;I@%f0m%c$9s(0X{D7yz+-Kc0- zStA1@qnO9-u{NrdyKBmiU~AA6GtkeOILYt8%jJ*ZJUZ*TpWrU$ymk`~ zOI~8Q?7`+}HC6o3Y}JrwnN;8K-*xE;=(erl@;Hmf7gl$Krz~!l;Zjw$%{GwP6;Nf} z1r=@Ga0!d-<_0^gYE>({6FnH}sRz+;Df_UcKW(Go(jUGi`%5SDX{;Fi?%w>jCMPFL zk{M@I)3MzOB<=w#>cB;S?d6cwc4SWK=u1_!@&FB~|8@tUa$1COR}HBgjG*$2qo|?2BRDH_x7f!ccLuZrV=QZmj1Tks}qLX~s zUeWJM?v+u^g39@bfV14oD|sU;)(D?PGq>KGhbQ8R_Mi|s zSNh14HnKietP{>;c6e9Seis=8g3T-6n1-x{w*AE0IF_| zeG+H2^25LC*8;nPPZ5*M%xYp~?rY#yS+J2ZPu_`CIKe9ItNv>^l6t zhI5YQ*HPEbu0NGuhcDIRqO6@4{Ph={!4zY}U?lce#aWUdu~o-CY){>`J+(({WQ+sr z7$k;BuudZOPlyHQA*dXmj%spCcd&8TP1->cFDbZK6TLR}lLle)b3_W@IoXfKS5!Da z=ZOpeRtzdnO50N$2gSL{^fel`Pa^Plv4ecQIyi<7>MWDx$Y{acuon?+3NFpx%Ont% zN|q1Rsqu|cw_}K7!7QH2QU606?NUm3Mr=#ga%P&kVFcL0ak;2Qf?WLkd*!%Xz*Vg6 z;(K$)<$`NInx?LCNJYmbJlkF>q7a*8<`FL)@%wNp6+21G^q%;+y$mfHqaG*!Z!tza zo>_n}z(QEtylq>BwOz%qqCDNqaXH)C*sL|?9G901a&_Arm!Cqx+RBk5eMgQQsqxGJ z{{zv>ERhXO1wxYgRSleMq zPtVRFJ$>U_R041)6QTz2*6y8cYN$EInz z9K7moQuzvz0ZKdu(DWM2Og%-V#UbfvK8!-3YEEJ)*iz<<40TOegzc{uB}EvoRY?(h-~ndhPb#H7lZ#U@d|5UwIrKDRAjH5E^hk?48;}w? zKx_XXv<}bG5ug_0&BTlC3JHy>8HK5?8^}rwY()(lsBU+4+YQnr%P{D?qc2=VDCR zz2~+9&DL5QTeHR-G`sVhnCSM$lDT+vteuA}Pp*(?6#Uu| zX!iCa2hG;OQj^k7>&8wUG`nl;bdOlOfWA6gyS{zLq1m5$1l(yA7F4jI&Bw zfMHAag1raL{s32eC6X_(n1QnuBjOUy%+^3|85w^Wz7v4L;DK4zvjLI4{hWM4OSlR| zw)|W?@yYBkoRTHiGC$vV4oJ4oyONgAo*M^1Z%(}^R}w>7mT-h2yh=kaBZjM8zNZ_Z=WT?#|)n3e4eblb#`28!O~fm z9*K(Z=vU=coORPj1I>T>#qz6gYrt}fitBi9o!`OF6u*NdhfrQ#BOcHc97e-%W+;TH zLYS`kZhrP2Jwwj8!wEa^GRnpC23wGDgV)?FAlQ8$T@LUA>d>X^eTs=!? zC)^>EI1SBdQG?W?hJqGlu7#-=EoTtafi{9RHT5EoMS+r2X}*cpF@zV-Jzp)o#Pcxe z1fP0Quh)qX_GtF{sTck02O5L!^#go8`(R3(z5cDU_Ievah&x$2i^}qR`Q|eq-wbaX zz|pkLe}yxP(M36HVCJv}9%I)h4p=k_?F^8>_Dw_IjMz8k1)8Y&xE20Ac5b4t;hyB* zkDZ$sZY1|N&P~wb$oHSr1S#T$cb+^qL8IQ{*>Jg0<_uQndE^xyz<&QxIyp(ts7-U$ z$4Hse7jvbl50iy8f8*>+)k!{$_Fe5IEdVrO9(&Q3jFOiy%3)q|VK_KtOLNqysT-Un zUcv}#euVrRBkc1tz`rrV;YK}s1VgJg`u!!6!~B_-s>?5;#aTRY5(jzvFLeQVlkAAi zGVego*x7giy^p=(9T>jNmZP`j7hkH*@&yZGjfod*!7)B#3)i~f0_&T5Z;9Qs{)!0L zml6i+u8CyqnuvwZ!t7*y)*&PI>_EK66?-0?w5JfPqk6^x7oY`OGrWcel+?euXln^~ z)L9AX`6}3y0!_FN<{~eIFqD_)3b{Nu;harCrA|kWohk^qh{IPn6p)#+(rg>kaDb~b zxGG1Fj(T|GEbk=2a0GlL(wqp}jggdh5;O?47`GWUg$MD-L{+V`=Lq=2o&iBlW6_%FFF#<&2&Uvhq!nmD9M2-p&MBi76Q}X~};%Z_{jF z)||R{5Nc#+a?^P7_!tKZ5z1%`CqfTn2@rE|Ka!J&LE-g@)^HQLzu48n!OH+0Hj<^h<`;Btv7712{n>Mfnt{R8lnkwxb;FhaAPRL5URgIk)DN zKzuDiC%~anIqGleU5;wEbd{rr8)Ht8DP&>{yCv)s?5lStM-;g?#p6%r-A#5U7<@18{A4)`qNt2#MZC_Z*_F`6e)QMTiRM&MUW-0Dk#OzRz za6OCJAXCL&C1wYGE4wRZCnHBTt}*GjvHf-akrA`vZSr40+{%sxtw6`_tVbs5Meg1A zn8;lxLuFtEnOe=_FeqweqVFVXbuv5{72T`gT9Bf3z~P`UJU9{j`zV6fFxoev#;{t7^o_;**ut_fX5F%=sdlni%|W>1|**IynRuSKnrY! z6}^!U-qMWwFi1vukUKzkeHI@XB*_!NhZ=+9efZ4+0b^0fx0lfQ_xWFtr0{g+dT-T5 z_|dW5kMPMF(??7d29k*?dmIaIWZ#!LnpZ|1ihIkfl zoKcJ%PDElO4&QgUOSA@&QgQYLNOi8FHPb`%2q7VQqh9hDdJJ0IgN2(cI<8=jfI{HR z5l4elmqkTdoVrG=0l&;6|3plg)Tyly)-$uN!`QWhJ-}|Z7?-X+Apb!x5If{jV7MlJ zQ*>Jsh1Etv%?IXR9o+|z%*pA-r<=0Ds3s8yqwtR<39O(fEg4rWn>4y%Ty>B57&a>z?ImL%xvjB4@hu4RPT?Ql zLfOUITqN+MCXuf$fC#1IgF+OaP@G#2A&GtPkq2f~r*5LKBa5#b=2V#w$zYQ8(%w?O(ZzXN3(z8=H>swID% zYVh&qflnd{Zm4&ESUf+TEhyw9p0k?>DHs9J z@6xLPEG697Z8&<~4@YAggz-Lz>6YO%4spope3_qyFc+coFt`_w?`>B`iRP;M@8vqr z$1O`d!sVH_WdTr)$AewXfhxa9fa;tY2}YyOyoc-DoW)ge`nmT+2Me2@bQ!Jx#e zW4fAv(-{n`<%qBuH!RK?B2qEXOBfbi9n7aOBpi%Pu+PXnb42bLiTSD6D29tkpo_#7 zWGXZrj|jVvVN_mEI%r})#i)|GKtRHz2}b2$u|`0tC49<{@Kq?xz(Bb);EwS9JCk&{ z^tmkee!`Q!=BzIInB%@2Q5~oQQxy>sPR7;H{F;H<^{QH}T&lUVd-GQ%XZPl>t6+NV z?A{OnoE+Ngp_hlnRop8LQy8u7p}hxjYA;ZBkB9c+?V*Gvc4dW%D5|MpCS9(6l6>Sl zQ;;KNEVj#I!rBy}G(w17Wl*6S+YbSmZmlU&A~Q15Tz#cq7_}6|#Jf6Z7qGh0>~heq zo46#o`Iwo;_ zN4#2kn_6Eq%~97LyZa8Yu&q$n!Y!wkw zL7~W|3V@GNnI|Li!liJ;?|G-COui>*DN+dVcvJ|IQ|r0)-3BOF$N;V z9?Z*_hCV_05)I5SAdaXm5NwdGuUNKM9JQ&tX$#{**lYgD*h#}>DT-Iv6?l&}Sc2ju z34r0tXxS{yfBxL)f$HG{hx-d=W?nC$WImGZ(Qj`~Gk{#dc+JLKsDQN%mgedK7S6}^ z5b|%JuoV(EMi}cup0d?y_hKxxVWP(aRDD7-TPl1Kn&H-!et)pN#bK)|I=V&A{9#G_ z!x-o>ram5~y`fcQcO~$PtHB(^9!%OkXDEsxJlI!QK*-_{JjeO=vsB>WTn>jV6aiRN z+=_KqJ3y4QnSvysX}h20FFItI%`NekjpVsPgn(&CZ|Zh)dTHvZ#qhn0lAZE!}9A%-6on# zM3(ZZK`MFdIMBvG4JuWEd2N7HJz*QsIDI^v$ic1Oaw5m1RGTdur}1)@vd8XQ%7rsV zjafjXx3CMMzYWzeAf9r$jDZkSIp8Pf-awj!DEUC_x6N|IP-F+Wu@zJA@8+NvBc&5W zalnfOFIst2;=%*f{u4tj#Zmc9xrEwJ*f_PI{TX6RN~3yZ*F(uN zmK>a+SP7KYS#BqM;n731&XUwfik!QS#VTrml0!sOD2qyM`=Dr9fO2SrQKgOt`sRD$ zfnj3E|Lz}9hGwWb5COXMW~|i{^(V6wXRf@Ilj5AhW(cM6)le(7gT9@DEUT58uK>_C zCI?(i^WneihBUM&9vRxAz>F*0=*`&v+b+#W7!aBpiD~!9%v)S=*}D=WkYBGZZL`U= zX>QORDGuQWAnVl^7z=3I=~J#L&qKG~6fq2%8$?V$Sk__MvO8gG7O&61 zwAX8`7DxiS!LIF2AJpbyca&d11DR2Ir)z;=j1FH<=U@gC07^$j2+<#YPm{DGQ*>aHFcae{eky%bfG8c3}f2OQI84SMA6$VeLkpP2VGZ?%vE*Lyn zfWaH%8m^!ZnL3h2#xW5^7~Ffr1N+UNs{8H#?(KI^aJb&X(E#fhZUF|bbEvP3=xBhu z7-T0HjKLEGCr1OUwl=nEjk%)%ZjYylHf3OSyxb#l?9nY^-*_|tf)5V#ofxcDTCgv_ z0rEvy!hK=iEGEHFFOzhB@r(cPKlUMIhsOi-gm~R)0Eb@bej30}++%n~txKg;l7GQ@ z7|$L}PXq8CxvlfMwx;I zN49>zT^<*|Ex=E@lI$FSWMPYE0Qhz3(smnUTNS$9yaIm@e%!+0P*5F&qYL;lGc6L` z?pzOsdg=jGG4=ve+{+mNTb~CnTD#6e4`%@M^yU=a28U%04$H#ZTi~smf?W-jsiinM zVqYIB^Urqx`=+5XTgSe{!w4JdsdQZ-REC2Q{9S_pN({kkCVU+Hy<@^>j~If#wHy5X z7IOJ_4SyZk^%N@8-mWYQ0QhAYP4&})3U_6Rru9&q+sxxA4%YounAbftiO;T4RpCru|6{t+J_mkvBJ95#`lA#qLqmp|jr)>872G2^Qcl>gd4n`a?OH ze)`#BIT^EoljF4@#5d7lMa~4ZD5}Mi7=+W%+0{vQ{*@6((o?1L8E0}%s#XV;)t+95Sv6^Ay`gsC zdSOd<8@XZ**F)@q3EXZ$OaUi27KM~!cV?fm0!H*-ZA6q}6XeUJSM*;QL{!4DBVM)R z(IZr=Kh@;2c(;O7Pj@IuC*M*$l%$TC=bv7C0qB6?%c)~sLh`4Sj*62~ktEhCFG8Nf4d2BCK3zET(; zzVfz-!F2az^dF7+2Sc!&4sa<3%h}%9vf84=)8<-a{9aYL(}27K+h5~SdsW3b?#XJ( zE=(q~(uW9{l>cF>S_OW)bVY_g*MAqc<7y-~$^!Od)kw~%6Ss}zI;ayXdOV2wFEpf1 zEaNIxW~Gs<6U(k)zT_qcy-VuE61tP96HC?&sS`KQjc8KurcNy6jVxFrPMx?`kl4Gb zPW*IF9Ppt~CpZ*w!9~$kqE0MkM0tHr@j<8so%tYA3p(*H1(8vXCucQr-$YJy|LVki zBvy64pi4nu-;O3X9FAWa!(aO%W`JtanQylrPOs+0b9R-Is}*N07= z*myPw5QurOGK9iBYwEy!@JMQ!WET@OyIAnks$ED z^sEH_Dz0LE)}GA;{;F#}3jEugfITYkSK@kctyb81XFt4!ZbwyQ6M?^!x3gsJIDvn| zW;dMWvoG-X1^&MMQ1--D`{B}~A@Dg23H)U-&mi!ZjWalbf73X_9 z1^xvm@TW`??wY{=Z4~&Ek=(q%pR|5t0{?thfxqz#%>+TT zBjfi1|0d-fw8v$Wgu5p2e=7z4QY1Go@RzI~nZUncgxA5OzoQJt*4l9b|MI@T-`DUPTMx|rRT&cePaX|{ z&tXX5&xv^kfj?)Q!3q2;drIJMmRX}flN}5RW=P$`Ch%t><;Qtm1 z{OL$;l<*d|H*G{0PKLke#XYl^V(QP7o(*#T^=A|hJc+AVmZ@j_!6isi8X}mmABxRM z8!0BhpLTnm7$HOmKbX^QH=YjVnc2yWr=`rJ&H}l_lq)n5-1S3Ccc?(%b&ow@$y^{OsG$ z@1K2J!ek*$g9o`kdS~CRgP(*LEAo(a<0vj+|V{-+luH z@=9FrD3Dj&qWk0LZ`rbc8L}r8$jf>*2;{e)mOx&@RZQ>l(}_Ta6o}$@$+gZIy}_9c zf_NEc%_FJGpEZxXs-~CCSc;?yKxob+2HlL7OiU%!q+n)9MX6CkurNil=)lxik9-@BR4xx8v z&-Z-dd@amh`xEB}I3X0V$k*-l#QDB3x`*(@`2{gjDdC3P7aWVUzpm{msf$W6ouw`c zJ#><~ObI=S?V>_q+VyjhZ+c04#Yx&ZPC%5j+9I2tGOx64PdnJEKm}*xUiB^<5z6El zcIJ(5M>*CWeFrX z*ywhmh|UzclVrV4SvQpRdI8;tj_4pZ%T8=2MRYb;6n89`o;IG60_?J0?>&|3t}45; zdqs49swX4gLy`5$p~%oTnUW>xWilhm^Idq%Drl*Q?0Kz-?0F3bQk$45Q9(iuIIacJ zqa9?|2I76(dCyl@&rmqw)IFw;Bi|$N7_^Whd&Gw3JSN;xR}=}{exR!k`SJhB?Gr9O^D{m*qIqeD$(*L)_&iy3reVS3vx&9!z%k@WxyKpGt zE=!`T1i>t2M0vyJyRF@T9AbC53mJ&F8wB2gOFY7lETj{6k;{6AxXVH$SI=FpIqtGx zQ@O+3U@f09)-sE$U@db`CDwo;uf98U#P$J& zqIv%EQ>j(Jn*h*18VFdeYYKo3=!OT*K(}pITN_F-i~tiIEdwkUkJl%b0Tqys2l~yR zlCGNBop1X%_yp?iFIbMyRE-pG_S;w%FfGA6V`=J~2w2LAbZn&+z>%=5U3mVwrr zI$8!=&GY`@F6McEOYg>kee-;Ju*K%)`Nel>FW642fb)9ZX-+5A4e+^eLz3WeQ7RYOCKNHAzo_z2Ec@-T`1oEm)f&}ty zbgwsoyqq_(Y>ha9eADL9<+kq&WM}rK6>Q&ME{o--ae!%7PjUhd5<7Y7&9k(%t011Y zG)~l-U;p6}{l(OAV9d5J#9e7q^xw!(LO+3c@q{}ImeI@m@|ctACWKbn2Hh6@nFv35 zZlaFL$j-SzQ_?(4NwC+N`}w4~>20UqbP}-`!Y_PmTtVlu6!Q?&R>q83SX)VltXd80 znY^7DYsUqwU&`cknNMs_4eP&nZnRn%DVDG1)l!9(t3TDGv)!w)zDhNH?4N3KN#6Pa zYT3^JzFqaJeWPA$UVIn9>UrM_RjmEEOoI=(Z|UKsB+%9>*1m^!VpOq;wf}Yt&F)vR zhD@?E(B-?wDGM3u@R-A53lKNZwTkuEeNAQhtg#2U4t|u!B9lv{wLpz`^nUo|11MsR zQOMFfE9M!zhO@>QT)_I}E&_M=?aZkH++t@|g=FK{VOMT#i*H)PnnhF|wt)5N$oK&# z1S2j|-T_Wbn(`11^zk)kqG>CcHX6=-$l2Hhk6qDt9d)C){YbSx1Y#^0k%!x|2do)S;LtX zmBNV?yk5qE6{R5bmt{a7F#|dXG75cvN`r?39P*wzw4#~yy&&}ccUzFo`$t#wniBs2 zkFNL)kA%?2C?xdPz#Wow8$}FU0lY8ZFp%l$L*OD?)!RZ)eWhaYFyfzR-U+n!aZ*rj)}| znw(eVzuOo3-0hQy7wpU91s~G$s($?=A@nf{3H^C7(4gth8+UL*|LUF+`m~;V(|U{0 zSMl8S6(T^e=T4`qOG82>mxq z=uhD))@QmP^ru|&QRrW2C-j*H=S=%dj^pu^V=tG+4`9|@UR@QIiEcleA5D2ExX=C3 zl$nk_8P|#ef6}%hd=5C8vPXeG#yMVpJhv7+E^EQ4*;Vd7o@@Dd;@z0_2_wqN3jFVB z*00yatWFzouYS#a$@2By;f7>*Cp3fVOr9ALa981|h0)@~mWjO0{Yw*90NvSon zu8zPnecwt@q-ew>aseOmgkkT?ZtqT!~<~&ZnQJwwe5QI-%1a{1c+~U5N1*-(7jv%1GLb? zo$Nf=!Cs%``8jKTICb)Cw_l1YjuL{2)ez#LlkYH5f_kDHpl#+5Ce zFA3&>@EH69<%4;|c5*r9IZc|wtYd?8JV^5EIpWnwMqV_p8Y#(>b*gmRNGWRKS<=gj z9uGqK3y&)hZW&iGuPcw|NiWN;Vam3f9NjJ@y)2iX!FL}z#tey>w z<GJUPSkTih#IA#mJ7~P~?`1 zRFiollh(+9&FlG$1?^CT?U1Fsyz>jh^Ftj{UT_mrURrP3LduJO*bs5sid6m<4;Bmo zg6x>ov|o`5pwkuic;jsS{vvFD-F}2E$O*Xa(JV+cB^H}V*(t}GjiFrVB4u|!!uGc$ zQWkH|GhTr5b156{P~C{m5w;r$26JrL%gK9>S!m40V+Ok)je=Caf%14Aqb(%3uXB{J zOWBg&eavOM_}JPE>#ynYAdI|RDlEN{KyNdOH?IVNrF%n_@Wl>eag_bjtylJz&M=Tk@?47Yb zg4%K}6tRBO8y9u}>n}!P^*ro4Hyk$JqD|!vWBp&x!7ZfAXxwBWTgYo&dCR;W54`2G z##`oa6})A>z+2{A!yMw3UF0pZai;m|S?h*)%jKSV%XHqzv^C;*%f$!DTV8r(cnd}% z-ZCSqN_fjmMv|BI6mKE>=x8Mc1L?$DUryic+1tEdCP3x$gDNuc+2Gn$y>hqk>M>EiFnJL zs4C$ta~Vlq*;BlQ?4u)Z0R!p8TjV0xA>J|*iPiI#OOCh9*i`N?Z~1lPEz{{T8gH4- z7V=_O-ZG`f18;fVc*`WNg11Z+c*~?~m>c|j##sV2s0t^qK)Gjs@XU$aD}v29K>-vMK%52?NM&@s|NT8 zGnSbSgSw1)BWubhc`0Y5&&gC`Zpq97N91)zNkIpOd5Gb1eL z&B!KrrdgVM_*ALXoci8#qm^0}`AUc;!}oQ5$C_$oeLqoeZlE?gYTPwHh41c_KJuiE zOeb$BT?x@v(M4ZwKJ&@uGvCuJeFI$h7ROYrR5_eM4h1jw3)K93_ZBD7?wEIREQV+t z9}~k8)L3A|A;h6DHfKmpRbx|s|Nfd%bW7Jwdbn{Yt>Ml5onll(ZLB3KLRE)fkHeX= zk6M=3uq>>8t}(na!q9#atRF$=AgR836*bd2az;nkQ+^7&Jq0T#d?lizu}>mI3Jo*| zKKY5}SAAjvRme9_@O8d*W^=QnngHq;qAW3jv)<{e`rEJz+1V-PvI;RmypDWiD`j#t z#t!j1N;BE@r}FF1`RmW+*I)40Ux;OzF&K%Lb!@0$2j(VPw=LzZz_z9K2y}f{YVl<5 zUMI^qS&0$o2SY^9L9AM%7|~;N|C1J?2HbQ;WYsN1EwGh33H(&)>Y4F@W_f(j1s)-) zP7G%r(RK9$q>KmGLB3uc976}O+YkyA`7D?lh62kym^6Q{l0aB9oGg&}nQ-SrvUdwM z>SOJm5~mf%h?MHTmTy=|36G0`BqVD&ivzx81Q;PV-W98OFRPIt7T-RuIF4`7;lAo_^vic?aCAk#UNbHI19u#D|&}}DPM&5;oXqp zfzmrA9go&3wY~#KA$49E8N_&ouw-B(6yu2Pa3s}(80R`TFu4VRaOWpL*6qs#3drWQ0j$n5bN)MtTTc=CLpbO)BfyGWX=>@?0oDv-t`L zL4>Y%ZZ6Y@E#iUPwPX6x(Z(?+d5@Ay9W%L2UIlie!Qt5~G8!AL9rMp4qtVZ5{Wx3L z=C@jqsG60FOrHT2oFu-rR(QV@8o#Am+|8Ii(%Anpw3C- zhzCiB0!aEbpO^rv-y9^7z4l%OMH9HHN0O*&UcdmhDX=<@je*q-j6&#WLGne)H<{^z z@xn58H~zY|r?Alu=SFeMaWiz%;C~y-q#*bh1kV%{?Std|4aEwXHKNu*At8Nr!hMBg zR(&;8hY7l6n{b{}jMmdO-3mq<<{rUP0-GH|-wz9jsYA*?AU4yGHqWitde^`;+wEbm z%~9L36bJQys7(DlfUI2Pl-a4&a7xHD=bAlx?%;ZEZ!sAHypaHn1K6~PrQ$Hhkg;ZEh0#$inv zBNoEFuqA}MajXR{Zyb{)$|2l)$0W`|NY6gP_4y>_eT2J@aKUvx=PVb@{gXWSRfKTQ zK57VeG72d&)=6Wm4&k2PQwSFc{+*pmzdeB%UYYF;Vt5z^Qtpayf9pQN-CRe`!1qIr zaMyFF;1TZKV=x+GtE>|?_*~3ibqM!sxZl<=L&14qO7WV_N``Rn7^Lc8!(CM)0pWh} zm~6N!xC&XbdMvl$uDIqS!o9`iDB5uMNSWs4NI|5SWdoWj;B*t+rg68Ys*Q_zJB!wi zE8uj!09dn%5_DVijkWW7O0%K}_xz8);q@G2r=a@`t8znYndV|Whrh3ijoVkxp^hmD z^&Ft4_2J}WZ>2<9xJO`HgDc*2!#Kkpao+x> zZtxAB-Dn|l9A#@;eA6<`j9--UBAX*P-;m>c{jn4T0%8gl%f$ZQ!O(WFaoph|IgXES zkD*P5$>u_2{2qQ>bMRxqBw_A_WfcgTuF&hub|rI{8NMP9+?q-2tF=Or+`LI^-ujUV z{Ht9B{+t>K0{=56@Mm!qlRsAw__MD0DDW@uVSzsr*NXyw#+y1Xy&X>Y$Tr=5s z8CKcxS4LE=@iw~Li*`>}d2=~$XW80u)f#Ww%m#N9o_IF_SNqi(ErQcy2f~O#%yjVl zGj_TdD7Ig%(MLn=a<#_O+b_ix&)%Z8?_9M;3_&7%MeHz$@D^o?DKTAP070JyD{3+{4Ch#wG75I~CBnbT1 zOyF-Ek-(oU2>cBM8?%0D6!`a$iQD3B-vhe%ItGyF;_K|V)5Y(i%RTGjt9d)C){fJ~ zZ(GX4zAo;PTuGEg!~6cp35=p(*aG<7BYJYesqL5IyRD032om9I*zeB1NhM*;_Pf)? z@7R9dBf2=sc6QdqDPMht#rB_^!0I>;gD$=jxwn_twf@ps0h|J`RxC&OXbR;*EFS_QVXujS~H182zd?79j7h}P; znRM}MJ&I@P;&XXBbJmX2#jg~^^S&Dee`*iVIv!OyZ;N9$~ zWHn9oC}mQ%q-6euyv9OY+`M>bP|4?wLHNTA_mn(``Mk3{SB-9_Nh9RdN1|?XJRF7k z!={qYM*i;w{ADNLXH6jH0)7Wo@)s%hXCk?Ixj$q5$mIT|u5y1`jRd*>hROXYT*dlK z7v%nwYd*^T3wv1ZPsa74+@G}VD7k-rD{_DRaIW4THuc_84(_TfgcS`NMds_i+~1e` zkPM8*O{5$JusHPmF&0UXf?@xJ5oD>Zu%d8nsK#^G9ty}fmxxXYi%(+ zarxh~hNsJw3x1Vm)h453VX-O-iy>bPha1-$Fj);XMnC$BR4u0<_-41JAh6iUapc5> z6GK_4syHePREHj;+?C9W-nQ5!eT~&uieYmo1dEO%B0!DwkORk*oZ@^T91kbAek_#p z^uzAb7je8SMGrk`DKo@v7lYe-Iwd)ae)9*%DpzPR7BY=)5-a4>Lu7qVFMl&VD7mLX zWZU)TY}g%&konL`%{>!LS@SIzr~TS*jaID*SHZ0DQniEz`4?)Ijl{oHvn;7$1`rqz zOlHlp<_ESP`|P&o0z(k+S(Fe7mX1Z^iq3O!eNO=&SQq=^6+NP2#XauA-Jy;ferX{EXO*l#{;nW^kJQ@GJ~s_ z?b*Zm=_)g>VK#e-gWIJOpr_HDjsz^s%2%cq#o;#*HwqSPlZygP+i{0q&4DB zKsaB(B)fXL%JaRjxQF5dXpBUhZc0=oPG>|om67CyJ;m#gHPe~bA#S%5qf&$q@#+qo z3b%16P&~MaiaFmqWJ=V=Az9LP_ymMg4&}UM)iumbeVaqwCEl_UXPU2Gv2KXB+(I{^%F~UvEaiZ&?;qCA?)hBgvaK+k3=-ME21!8v_ia6K_$7!VdA4#Yn84w_JC; zWznW`hk45jR z>RIcCc+2IUdCPR($h0-$c+15H$y?t4$nX}7M7(82RF&|SnT#Ya?J3?u_R*2IfPr-4 zEpmhI5O0}^#Ois=1;<;aY$|t{w|tPiWinkx<1LffLZ0u+TQ*>$NKc#`6K+|@Rq&RL zu^hLoj|q;!ynz!ZVNl&I+_Hx5Bs$TWbwj-64!Y4BZdu72S+PbOZ@Fb>>O2_S^1erg zw_qgVEvurcgtx3Z$}s}HZL_^ca0}T-N8SPk(uudoB_9limasskgGUAtk+88stVnxoZaQH=!j^7%2jlNN9l9AE>gKcmPGggzerbKJaFrz_Gial><*4lA# zqn8V;2~WHm7t($KMKkt$FLoFA3<)&z&cLfxbR7+F56HA>&3XsI7Mk5Jptzj{6yMv6 zFa_7%!U-?i7dP5-{0K%NK{_YqDM3o!KWCi5#gAOsQ(_dpjLu?I^>{h!I~Op@ssj&O z{K!mX{1EeSK*QJI#QY4GdKcqIo~Iz1j^ySYEYsGHOyFPaD)6V&ND%n1o4}vMRjkic zLEuli=A*zr-%jA~!T6DlgPHK(I4Ipn@gw&RrbamOS;Dr9_v1$zJw>iO?C~SdZ9n$8zxa_Fj`BkZ&T*J%n&_0- z1R(u!1n_~Ea1>Q%926sBc+y>S9n3L_pItZRNG*ycC}WO$#Eh_+Yt{4v;GgXeBY_3u zVGJW#jgrr!pWBd}T-sGGbP@e*Lm0_PqMVgTR37E57-2bA?=2&&Xwb-9y~}z$;G4G( z%4E8PtH3wQ2Xm9@l53cQy1~KilB;(S-APQQi`EU9Os{9?q?@aEK5t~+8gVAms|9GX ztFGSn^up;LiZBw4MC@@vRF#-a7c!E(wx@UrUqmusNc#9k_ zJH%TiBe8nka^CTlNt?v}x!mUl*kTh?$D zyk&hP$1Q8FVQ%m{BfE!NR?(fr-m+@l5O2ASZuEv*mh(oItr5ptZrUV0m=LvR9~s_) zk%+gfh^i9avXYVHEt~B&m-m;*_18@19@s@d91#ej>@RoVkFo$?`7kSHEoN2y#&blGqa;0b9 zGLttlV~sf8a_K?xmS-Lr-hz>cxBUO?y?t<9=XoD^?zx`;?gg(TN~CPsxj^IuOr(g` zdPP<7?C4lN?=*wHcK>G0(F?a3|Z<+JNYI(~U!&~NbD0i5* zOp>?EhSR9LWj30~(*t=+TV8j(570J>0U1<^;H9Q=1{Y zG3KtxPa!rSFhk45cdCRJwMuyhui%*M4nujpicH~A=1 zC-{i^6?xY&mY3_I5Oq)r(6UmWEHp**;9P_%{oDMHz3Z6Td3~vlXhUbxU43L`f)RGJ zCm5i~tP|M^(wE?JlnI)OrV?8js*|)zley$e6_ z{W2PBn#txYYt!)IhmwnE8ei5=IQMiF>5WL$qllZY)@vNY#ki71t)zx`QO)^??NsZd z;pfpieBNbVT6=_ZGL^pi2xBne#D9b%I+ecs$V8pBVN@Ss_KG^bJc_oVtd5_htn|@F zu~nH$lI+^XKmMiaMI}e zXXmawGFi&*Wg@MS)~I=JMDo|VEQKv3*LpOaJ)x;bKq(l&U$dEhW>4^KWL8SE7cjKw z!ikyVMfdsQ>fadu!b(2*NF z0#*B1ZDz8N9eX?>H8NQ*!&7DC5xG=MCd-<)hj$R2u6J5;$7J*YcS7SPORaHzlE0fX zlNAIwN&X-HJ~{&&5j@|TndFI%oTn)nANS;$3wkQsjjJz8wO!@PVoGiBaHd@mB3(l0Tnzl5wRS9~@BJ^^MMW#EeUXN=xrQSzJAV8W-@!)J*U^3tHL` z9Yq$PWo)c3z*PBG@dD$XGU$H~^-G8(k85^CWQMjYClIa3r1Cipc-`)J>|lTpRL`8q-0+Oiip*)~YT1g=NZc~z&gPsGrgyzZptYh$8luA&rDb8Rg4yseswDV$yzg97W+ORg2@ zk_5O!#ndp1PNnRf$JeWpg}NMS9;lKmfz8UQk}GIVV8L3^W{3srGMX`*1#3C3WLYaI z>5yHF$>x??O@=!sacIzm-}b-WXi_sRTZ}_ z?>Y@z69ChofJNkq)$*zfTyR);OFEQ0Y{7ajdCOurjk-`4qlr8}khd(z>yEd4MS06S zO2Jzea=c~URLm}(-9_Fq=SP~Kp3`OsZ#gqGZ)wMsw6zk$TTbmIZ@K@D;VtNi@RnJj zs(`o5MkIN9U-1^QkG|G%Fpz${MVwPR#9OvToiw$)<@%`dmaS1y7I&DpyobDH6RmI{ zRC&v$e%-*(H%A9W3~k8kj<>uqD!64GrQj_aqcLt-Hx+Y%Uu9Q!3Ae2Ik>;n@v>C!% zuAmvi;g*%Sk`=AQ@RrLuNP818bo7qlE$E5xmQ|sufVZqhB>9Stc2CWSIAeEl3)x3s z-U0^FkGF_(YKM4B#}ljNEtd>$>F7}IFmE|V-m)A{qw<#JXd*8TmUol4wEZ-C7e(7l zrFBu9viv3X>Tit@^Ek%x_K1L%O_YMMY>o8u>Tiw+DuZ5#ga{*h>($>tV*{`LhBi%H z6xYzS;k^25aV2Y7iE&X}8QBFFMMb>&*>AKv?If!-&wjCuze&!ykB8vM@A1&KeEjws zeSQ4)fde1^&HDK7J8)Rs(GH7s;hTZzTsIt1vE5bW7(HS6?mH|(mA}hj(WUacC+bxB zV;}#jXOmXoy+Za6F|f)3c*i*`-bDer5>BR0;7T-|mvuV(I4nByx|5+VsSI64DP(A8 zBv$;FO~o9tizB+o3rHxYXmf0L{X`71K#Z$Y;Tejdy3V6#_O_T%SE!S(q z@|KObk`1lI@Rn<}5P|P9Z#lfHyyY0CR$|+Zxma2W6-5?1Eq@>`f6$gc=z`-iv{-lu z8Np$D|FC~=6JzZx-K3UH9c^pp*3s^XUUr|ikbU%3{J}u_@fNY^?+|ZU_rz*>%T-W1 zhjLwqa))^f4i!d9xo{elx2*B&xlH+2bUHnHL6oGA>tB^h9EW+eMmU$PpcEWtwH9Z} zUoqAD#JQK*?R=*EyHEp0oCWhDcV$aj8P85ebr*8{D>@UJG+Ocd0y^)XK)kjjl}6oqN-qB*DSUx{m)_qvidywV z=FiWJ*DCj<_uzl|W0`p?Eha_$PtInZN|NmA${B1JXr!2g8=TAhFrL1)Qh>byJ34sk z!muYYBP~5f9}OJkeuFYjWoGobQbYFk7irx{o7S+<87iwTT3c;3alm#m(d2>5t~#6d zew)={9_#mxwMJV=1Fd@@>W5)K2?nS+#!S98cIZF+d$!u_iNM!Qia+)Xq>cFEiLpKh zJYx*Fn%H~W)&V*C<$z~5@O5*{G$vgtuwyr%0-=}i@Bol@QBQkl3z0=pA^v#h`&xII zsF3>@6>=B;(LigB3Q+=e8y}Y5|KSGAYf6!vjh?fpgewieXiDrNsQgwM@Pgg=!3JP% zdNm+kHaqrpV4E9%y2;G{kVMfG6GSAlMKO=i?~)-4-K~PAmKeEYw)kXk zGg^q@O}5}!MDLp{yn_?&`d&!FUGzfm$}&1=a0$8QvhvV^^3aR>3Y9RAyt*ixh|WvWM1@9FI``l8YSsNCRC!+GWq>XAQq(JD$Zk=+Xm( zHX^bMl?DPC-4nCYc>}8!6?y0p&nbIf1Xw<1#DlqJT^J9xW<2iN-*}@I4N3^>MwZm6$uCuUQiM?!1`PsiD4Ez5}TLT9TIz? zCccvYq1?^&Q#2Ga)x8HO93RaXilK(&1y45*E=0yCbx&OVD?Z3Cq-{nqe`}_ zqA(g=?|O9)bv-cKxkq&IVrGKPZ+;;-`Cr6yM*hpjO$c5Rvgf3-Ey{3G6$E~Nr08_L zbTdAGJ9I$wM0jdDBuY|CJ0i(b`--bVXY0>Z5lGRG9f}{6Fl7e z#i2GU;qI`mCx~|gtuUg|J9#(s`-ye(Uel$M-@3gn?>ffvdQ}+98cM-f)~nXZOP*!< z)|#oAy}VN0hJ!bKqFbQ@CipLfPxs%rJ=V2xn~T=MeOd#yM?o zvYJWUSrZGfDoWZIl(aDsky$6Mq@$H!vpTD}6fqrn!+*Ye)Odo9ny>f3CmR*Nr>YW2<(g5OBcqTea;27J3kFa`R#Tt=hyA zd$?6wc8c%qR&CiW&Vk}S3FMlmy^XkQKyq7cH=I4R%k`qMKXCX z!et$Rw2s}{5H!NA(upx}7ukQ^s;f52gbUqUwy~dkZ?|m2ssqIkl-HfKd{L$40!qQ#7ppN0UoaJO=*|%p>=F#0M{@!gKCjIX7=9MbpmZsS z&>aNBXX8p{wGsovPe&4Qmt8Kfh}jJ||QaaGJS@B+m@sG}H+4oQ7q2PQ$W1 zr(s#1)3B_I(?t8v0H^!IaD+_sgW=-w+#wj=_QYy=)+qzS+d7mx48vg}MpoHM4;a41 zMGy0Vh2hs_-)NSH;hXZVV=Qk~1cq;*6pUrF(hG)fn3~C6u2uFLhOeWk0SsT)#t96+ zipC8G!&l=aV0a-mnD0`?qgW>aWCG%Q|f#GK(iMY!!eEg1q;pmCL@CBi&fYU5QBzbNCry*?KT^J5H?Klm- z9xMC^A&EJSdxGaRLkr#+YxtZeR?D-_aKT~W&FN6?Fbuz&otq7(QF+U3G?AwV@|L!| z?s&_y%3HR|!du!o-m+Czbk8ncFYg|2*+g>!-m}8nlT)2S&u7O*Gdd;xmw;s zPg~=T;VtNi@RkjXbre;(VJJrl^qP)#PZYEJyoKz;q8P_HEQ$dG>Bn1a_!UUAPoTif zr6nVy#Y?-$TbBJu^V7@P4B;&ohvqGdaV3jdiQz5h_ma23NPT1Tp^u6h-jTnP z4tq3O*a&%nc_rXuI|E%7JiS`>a?Y@q z1s%#AW-k(1H}9v>JM!nvR9Xw-S<7PL-P&{VuH!AwD{q-aDR|3Vxt9fT*3`^pe!9HZ z7Q{B18dwn9+BmTwovmkDkqDnSPg3pWv@lA;}&@g~;b^RYW^4o|%qa4+yYOCu=kd71rR~)$*(hTyR);OFEQ048zCCTNcA1Vs`QDF7lQ+Khpg4oHj#v%bB5hOFOQlt(6$wa%wMm3-&&c}s)5WfQIFiq+rL@4FzOH;ZC?&j$%@$h(fQyipX;vW`+PmW^UB6@T5-%r$4kHpssc_kACctQ z0h|UvxXYNxvb-^oWqD&F%ksuVmUS5uqgZ{w>HaVr4()z0T%1um1jA=Nv1W#6oi;Fh zR)=zjVYqBpYKPOPyrmsY-hH8}fVZq0%25Kns-xW# z#gG^5ZU7?LM_&~m45S}#5$pX9@s?Fjtd_UD!UYGRzN$mH!@NcJNQcv?Q@0XL z7BQ;K`DyeKLUU#+ZG_Mn%U|LMp;>v?F_!0)v9wVN#xk2)^C5Ej!I-B1ac#Fv?Yusf zh9*Q9m;gYTQz}DZ202C(mn?jzv?Ctqh0uoRb~jf|lA%%L`>5)X^BZv`8(K+Cne{c<9c{yecIedUnq>Yso+Q)A zyZDFS{;fa$-M>seHc{6EAayikEW;y60MhkH-#j4o9(h1szTRo$4D)8+;~eY*!{-4J zI@~+kq9ozi+dLrg`O~HEE!(1ue_Pbi?~Oblo8T2u_|T?u3ll!{rgDp(s2sMtE>zC4 zyvEP6yvEP6yvEP6E{#759||>oJROG*b!q(Wi8?j@IDBZ`vq&rNu7bZ(3aoPg-f_n{ z2;r{z$@KDb%}l73pI3BB^X|7*dDqF$R|}%_ub>q2bG2aQr7NkA;u+OPrI(<*#GU^4{`l>HS&Pgdd79ksOokga1tHS;>2lI<{mqr(;3Vg5#kLBr82=xH6NecLX9Se9_c`05F?3^D=ZBHz_9WC4;Cvu(Zr zEvrNY$O@(d!(rzu=(-;>%9ax+iwpd~GFV0=PnQk*Rd#uCU&&L(s#r}Fy^7^2g>9d3 zT<#W|O2N!VML0Y%AxW`ceq=(hn(W%2?~=Usk%H(nq?<*Ny?l8jlwpJ$CTRKi+E+Ss0pSqo5&9iIt9T% zuwXh_4mD#2WXP*9Ic{Bgybw;hPV_=F?dPn_?di*#m)D)>eL+R<97@sP`9f@OpEDIx zs+}q9p1pk*%?a%7v)T-?iJe9>hO@VCB~c|mDcY?uiT%_bTHDh*#v+EEh()X&k|b%R z9TDWI0eom3OUcQOgzQq2pyzQtpUdNVmgR9h%eruVdGx!GD;Dm|tl~2mYjdu1wm_WLoTxDHec3kBX zg6G#z2&VFM%u_zDm6A;U_U>_%RX@V~@>9|XVJJT~EI;YQRXib87=DuNAwNMR=pEv{ zLr;XCtOzv)7WOAYLj0RD);+BRT>ZPtO~^1Ts&TvmMG~G1meG%!h~I~n`!0+?O+AMSo` zX1q}<7t8!#S}2zjbrt;>z?{0VO~%#C7Jzzryth3sellsD?; zMhaA#^5lp@_DgcZoJEY|cZ#@yTnB}zB*|X?)+;~9(}-bV;k0Gt3EWAtgnAtY_3@-I z_N#H5(c=GkX1rb~;eSb~h<{Ulp0@A5`14=;?iatlc5x&5SfeN{mWDkihV7zj7+Wk2 z`vti%Zf+E$#cWvioh^1{)Z9p<#b_Mbm~Y&RzhA5rpDBEP1plu+Q~dn*%Q$CC&7YV| zb4n=KLxAt72{A5WE5U@VdN%-GB7RefJ)|=kB|jhsGQAvC)xQwNfq>Ih=e4b+teLY5CGys0>4g%2+Q)k@F>7 z5`UsGQVj@Hh6!(#KJ#c=s{a7z2V5FZ*F!_K0 z6Qazi^n^DvvbHHu8x|T|cIauX&I9cqN{)x7#r1~s%xyGgsE=j~O(~)|vQ~^Z2Pe&V z=&IR+98#vrC)J7_5$k*e7R;%fVUZ;PS+v~3U}IXc9)5tA6QO&~Srx0ss`!KAp8G+L z8dS<)n*dJYLI&0M=`y%W#>>R_SL=A((<8cyU(Tes*-(?>8x77T=%m4MoJwDB@Ju(H zZqR7_pmey3eulaD#cW7JE%+c!nPDz|z1P>ISj9reX)!b@a_x1Q6dNCI{80V)7!If5 zBRV%-CPls}+ZcJ@9}5DT9@>5qG|C#}ZFDz+_3MpEvxOhW*BE;o9Emfq1jIJIg{Io{ zKnkeCnG_eA&ZG$9$2S&LRiP}TNpYbmpBK{BSEJ7_H0|d{VK35?pGNt4w!zsPz)xOp z=;w9DoJnyV!y{~sA7_)DNl`n4o(p}vjoZlD#s$x@5|bh_E%7(rg!N0$kTUEKZ4%J~ z(~~@G-V(*kTHAOBHZ84B)VRq*YVDfU4^*v%jladD7~F@2ji!6H#Q`~3@a5-Z19#?~ z#;3(FDUJu`F}0k{8jg*nAD9$F?zT2ACY;Em_y*dsHjZ!LbIt#kfPkwJ2SDOkOfKzy zwv#MEC&i>_TE8eY!lXFvta&U7O^W<2CdJ?tv7y$YSHz^)utj2j#tVyV*%rtc+>77U zF=YX`gttku04?(-MHZm--lWI^5K?4PT!dY8i^Gdoof1e!b5v!pa*X?hWAsGctkg}I z(c@W`*W+21*W+2{W>u_U+EEa#c2n$OSTkDrODeBpfwcMk!j;0rSyTXjRJr6uQ^|n0M|j5+XuGBya?a z1eXmjhg68-xRyThrvQs0J`gyzSONow6`o6IPGE;y(q@R-d;!fE&JMQ_SF)g$l(c8( zbdZb`%Ei=U9pdv&3O#>FrOw^ z&jZX5tEbs}9|hvUUw$Xz6te*idfwm_JU6G8BKq)g`aU)stB@MW{6yZMJdiiSE@j(1 z%Y!3=`MexM#q!`NVwOK(nP_knG0Pvc<-t+J=!u}zMWL!db6$){^1P0A&lSw7^DCHT z`4!Bv{0e4Seg(6vYXvV0=QAt#hl3T2r{fjO*I=J@zT0p3SGQ54hDgf z^HM#|l^eiYpiS~Ahj+n_jh!E~f{G#xw``&B0dLu=i=+|Wa=kt*Z`p_|+0aT1Z@E?v5$-PYmiOE- zyahcG-m;0Yb^?#ovZb3DJS$9DUJ&dqM%<4)KEhE_mN;`0l9H0l- zBuYA9lSM9~!~-<(g!2;QUNz$}=B2yuPVc_^?#kW4&_ZM9twK?bI8R}XevQWOPi50y!=gkPX4PXoK^xm&S`}sRGCU z_=n9Ie{jPmh*u*0qL(xVy!M4oJIO}e8Rzqg&3N>(L2QI)ImA|KjiPbM#Hj25wpCq| z{`lk4hpUQ{&uT_mqqgNt=#w8F#MqBFX!qjmzzQ%v)BJU+mIk)Uj9`ZD;cv{)Vg3cS z9IxX=KceV4hJc0+cHcHwLXlBsI?TSC4ojqWe)Pvkh+`Z{t;P=FfND%@q?NNU8luy( zJT!F?aa7K10xV_BCVfMpWWmdD6q?RnF?-0Ic8w(8lcb3?c!Yn!qecy>+LO<5>t1u~K67hK95BMkBHn=tYZ}W4n#uDH z=x>I=nytIc^hy*bk3!GuZ-J@R@*H$2&5T+`UTD-Zp-HG^Fb7DF%*K_)Sk|J;Xem+_ z2o8BDSyY5VMUG1nx5da$7J3g^=sj8avlGSEIJEhR0>K9yc8KeO*);(*eva*(Ji;GG z04tniBb}lV#q8;s$s*&vQ7=jGFhpYl=0Dab!8E}FR6i*vrjO(4n%XhOaK8v|B0Oy+ zId&ZrB=KqY@k3*+``m|6gNRHyZe31h55yFVA!v8C!~rCstD*)|A+AqyE*JcgC6MFvEaIr- zLDber<7geZOuJ#~tnUZtUSR4hd-CB1)+mxx4-Zo@3>7)$IU!I55NX_}XP<11aS5xj z)O=zKjvjpCunyhzu}}do**9+mv2w8}V*Q_H#>>UK%Xe3EaFyjru}~b0RkLq>k@&Id zoZGjISc~PVB34i(8d-h{J)+jo9Zyot|M#;6h7yd}&o;vc_<)Jb5m<|JtMWzH|XS|LVD{dTAvw)B)PZvJs zAhI2$L2wK)IC+RH8$E<`-U>vnv4!F{%8NKFswfujF(U2=A=y1S5vSrYg2!0HB2aGx zk8j)8zwGst4>v@NcSGX=*04?G+oX$-z%XNP>>J-~E#lL(j?Y8V8ZX0HmG6&x(vPqNpf zU3o z;a~VA;A{lPIW%3EDATl|_*Zmu6w7Zcg^?a07vxU_r%lbTeh+Z(Y29m9KNo)M-rVX} z#X59Q2;JQX;Ns(ihxqtrESk}40k?0CsWWqvVp_eKl*&Asn~2Knb`TT62qFy}&J*bX zV@z_JrASMlX&+-tun!G;7G0WCa zis@e;i#@VyreaomWekvhmprnoXinfYS=DBU*W?v6gJNDHrzY!aYHXrubwO_xpf~Y> zU|UvPNk=Ow=^$N-K-(^RP2M$t^}5KkcZ5e4JrVZ1B2*Q4WLF}RysV?WPrN1w334$N zFucSbS%fO}#QR!xag_k2_uBJ}wXQCSC^)1DUZF0K5$u@*XzA7~=Y8wgqIn$x zn1qmY9c@9gFiX^W;QDy2L4Ks)DOrAm_!8kqHSnV`v!yn!b5`r5et}v~NBk(a^ID_c zT!aYX6vf)pBTliw+8C)wvqS@5Ce%k+13ya{Vyuhk>~FNG6q-c@W|Q8}GyJS2d#EM-VdVKnS+>Mh#;gi>lK=4?Amw}JCF0BiTCSnXIhK_`PJGjkt#N7k9VLb=$$Auk$0d_ z=pBiInLMficD#dtJVJpm^pM3EGX~L3-Y-u|gx%!3P8Nmj6R0AzuhcTt@OM7e5ut&# zFcuP_jE$C7CO{XT9ruBJEmS>pTw~Q5!x`z?Bd$?1I7oOR_LvVB*XSY=>BPbaV@%8j zYZKR4wF()3qx1D3=#WL|Psv9|_KItagA_3#aiAmSE)I0WG{=FCW=eEI0ODO-W3ln-!eeM{*Il-6HBpZ^n^7$^7Hilo=2M#J$=Ud@Br=r2y0SSz6eE(D zJkJ;caTo-prpLP*6s-G}vwQ1o_lFzEy@I0>&|;Ds?1gAz?|2BrLO{SqM&?H2 zZuK#*##OIs)lEE)%3smpH_@YPpuBY}2IdNCb|Dev()jpzIxbEi9W($W#6y$|X__Wb znm?a)A%b^ne+${?o&WwLC?gW;7w(X~_p{l1|9+M{*=S%Aik}`&(-J~fvDOgC*q{rK z;sZj|I{qyRn0HR{zz%0)0G!1RUlx@f+sAsjthQ_V<+8m8dkWOldk#VoiC6QQod7@7O1rH*Ahhomm+ndN;hW|NUFhJ4VqA&kS$qro-Q<fhf`{bW(N5C*fN9mT zOELc7jR1cvOC`>t`Ar26ODM%GFON=E!aXKSrg{xr=LatkukdKB5OdJS4Kjc`Lo(;PE1TEKOi1S02!qI571tCl zn2O)Q(jz2OWFbUWfpcO)G7G@bRc_<1RvD0acPZ!M=AASt;(rA=CrVREk|Fi!FI7L< zNHGNkiiVO4kW~LDqxQt!UCK^LSAC*6OV)O0qd7|u{ZSdZR-y^SMr#tOVJJ#8mDn=kyb|mwR?D{$oW3vO z(MDec{Vj-CbFgkf*)at=xcj+%1?wIj1nc1LRt^H*X*tnNFg(y-KZy4r^=^b8B2W>W z+DCHcJ=qQK#=%X!1;%G~ehN4Le+6*KR1P(k2t>ULM?2JH^ruZNHM=*Ka zy90ZLMba`?e~*xir+<;e=jbe;nfi_54zpWI9mPy8@3ZH?)gEME5R{> zi4U-$MSlw853pe*K6;?j18j)ZwIP7+M%WNGzdHsSqA!9CH^7pET|OJijtw@vrtEm1 znEZy0cH9|k_`}~5*l;Zt(Lj2F4X+Ts0LH8-u+el4?{I8*jM#A1)4#=rtJ=p18@{3| z!TK$8cEc5^#9_miN5lZwK`Auem66zP*fG_6yWyqnU_-lA1~YRDwnO$+|1)O28(0zF z+tZ2&%d3ZH%Q5AUT9%cY9OL!H8zaT{h!s&F`(k%xi(1*cRc$?=LyCCIH$}yqi*g#m ziufMX>aB<)M=D3sBc&tgwEqvDOxh8P$Pby63Wypm<+fBX<6nWM_q_Qlg+ghJjF)8> zjok{)6p>7wp2#2j|7`%8nn}mv$?djaVrh;U(r%=>y}3B z>vvVz9^8cDjcNitkLKe15MtAd>`H;jOqxE-u9O}F4l7<@v>d|Ts76cMHHD5imnJY; z+Is_xiWnqy5AiRYsWc(ejv%|gayYO!}P=;H=Z3x;`BP#kLKzT`IyfdOMsWeJe8eP~| zKzV2*s%5X+=jCS29g@?#tdy~gcKg+l|Ms)V!qXq_E-HUd!0?3_|A5U23_oXJ_<~}{ zI|7Ekn=59SFncq!I_ipH~<@i&Dt4xf~3iHPw3q{ z_XKk+(S3g}W`pkgQ3@ZA4}0$#2=Dvrp+Gl6!tO^(C2*L$``+9M5N|uC7Xt3Kawu`( zpBezZrG8QI3BLh)bccMJZNmSMH~rSc^lPlOZ%VAA?o${Cf;Dg63J$*)tx+7#EK2EJ zca`qC>n^y_gQ3#|OYr6+$C7MXFS$HQDQ3g~?Y|OFwFlbHn{Szvg1l{c^MMHI&4;s` zdp;~i1-!N&+aBW+SG#LFc0dQ1b%@YC#jN(z+8yjbk;ZvvyS+aES9al6Or)TRydER* zg`!;Ony^DTpza=+wWcy-AX>V&btLqHamRP)1?yqP915oiR^@q!lBnu-G~k7Bx4H8G2s3rQf-bP!Knoh&ZI5YWd@&85UGDQB{t;+0 z?>>*Wf}03J<32|w6D*Ca_Sx+4XC{%CgH~M8<94CPc3| z+QnBs9{S25QWEY(fjvn5=)vpBHvH&f0b2Js*Q62$(q5~H zt#lQoAeOaSY%5(g)q9Zk3Wq%(WBCpNX)7@$ar{=4jR;7)jII&w^@_7Zu|`@lr%(ve zmb>d*);bMHyLbT7)COvi(Dv5i0Z8j>(i#dTMJVL}qzz$HRmr+5Anl$z4WxBMxHuzS zM>(MZX_xjDNDKF@x;-Y?(;^4q$uTO%cVkt-?eVQ)K^o7~xdTAjQY;27NV{M_+LGc3 zv6tPsAPsp9v3Jlf0SnR=br~cI+0N(T8EmgU_r`*}?%>&1usar&&Z87$vQUeY`plb( ziDb@lsCOx;&m5W)B=wooW=K+>GZBayl+>pkSJKu>Oj4gyF>0cN$Di^-bz~=xS-E={ z#o6qN{&-e7074$@u=UJgD;mb;dvk^(2-dCI%``P<%EkwveKYdqY zjfFP)sH!)A%*qxHNHi1=-iDb*L~&IW&@Ci_M>y^dC-s4|9u{G=B9}01lV6998g8Y#=-9d~iWqEM(5AWnO*V78-D_*;gt3@&hSqdu;5R_dGc>zPxkCjx#ZEWgti<)K zXg!B?>0H*)burS|s&gwAcV-4qi~B#sKK)Xo(MTI2C)MPRs27%p`}a%P>M5rEF=w{E z8>4_wmCt9K7HjYjb2RR-%l)EP{4V}FM&9k>hqa=@&9!byU8UPYK(vY6-Krt^hB26M zu5xW}An6ajXU_?+{n~~>o7>iN-EP#_Yq7lCw4EIB459(tz)*a+b)T`5%NAm$CAxu~ ze5i0=p9P?=^0)mj_lakSP1Irvv{vaLML#xm1slF#m5%r9m%{X=kTq(vX2K)c)OFV| z0+n!k_)T51kCS_|kW^}LJi^UeqJ1x9I~RH(!gN&_s8e!Ql{=V7gjbY1>=R2g^4#?o zr4Ja>E)Au2ebTr#4*qtZ~_{w6$-j0XGY#r_*vhsEkE-nxJX zVyL!Z^*zD{FMD#c3dORvBNF--2MYZqsl*BWZ>Z2;L@5S;DJS$7P4!;rpYJ8~y#rSA z_|Y{#W};(jD!gvAoBqZEpPpy%_dwuB;&#E$6@~nQE=9PFu&;7RfiLdJxwxJ=tp~vc ztm#Zn;Ny*35%`1=D)4`52AkCDrFtyxS(>B;ldLBfp?MpGJ&%@j!XAOEI5PLvg*|=B zxu!Nowx8mh)Cle%t}aG!atCN$y2}xuvbb(ux?{~E>o-@|KsPuxSsL-4J4rcoi$xYz zs{;xP>lZY6yS^NSD?0Zed*#2}5i)VDw9D*8J zNN`TE_XX;V3@^ozKB^nw_MK*T{dqM=)F?K;j`Mj`0C&K4-y;B*$ zdOy3bMEK+&5l;DP6fYMHzdaE?NP07|T##2Bb}B4S?5h?b4v8%X5sNUtvBbu4E@mn5 zaBoD(#7Oy;B=)T5-d19tHWGVQMOiGd!8{5gwxN84huv&PG$ZIg&Dx%ftY~g4DH&Ve zsk~5*Y<*i5E+i+E->!(QZxf{$=dDU?>)WJlk3M8j=$jSj;Jak&+dy*yTi=E@Lu`H5 z&G#g(jSCC1iwMe_5xFt**b^&J{UHF-za`p^?$f$Kt5fvs=dP>yo9t2)~I zL_xtGu>J}PB2)V*7IsGrNb|Pa`c^%$f}M!1?-edMEWA}6${n`#AtMluYxmPgoUfC& zVy4n2@V=~*`CXjK87A=V$h(fQyrhg}8Kqz>oyw%o)*ZypvVY60Um{-W0&%cytO7K~ zQsGU=3e7}XY~My>W`btFg{BlS7`IL)*p2xWzxO}YommvoJ?V;?^(3#NPl~yOhMOj{ zkxM!VP(P6J3(a#X!emLAND~su=j!6ctu;E@DCB$hD0R+OuPa&)F@t z*__=qL{FKV-8IZkDI3+C-ET=`?5G~(#GKtsjh-Q<3r(r=A!g|8eh5IA+`l_bZ4JV# zt~NB{H7N7;Wi_J#>jH3&wd!JK(;0M+Sg^o12dC#2sHQ^^tvH{ad$cuXL_DQCqM)pZ zzYXcR%^U)Z=Fab2Xkymy{Rl?p2HC-1Hz@(N3l6leV|WN`vbO*_*<{lNs;f3#HGk)GaU)%|jUSzwk>tWa z1_A|vn@)~9%J~%ZDVYH?vm{=A3=vJb|)2oqr=Fc9=(E|)>|&icdz{1 zaXN0~u!_@hqh)bAZnQp5>5Z=YF$?o^FA9qdr0k+H6zk+2AZ3|P+s#>mOAH;$b}m0R zPK0n$)@9#Dk;FRC-4-3J>7J-Fv!mqu7u(!MLlHmn{fp{6?>VZKlV>R{z)$Bn7(Q_~ z;+=;`+znOq4Fnj2msxa<*|p9COJA6fT~Dx$U9oWTh7+z*V@`V+nc>b@i42xRDNQlz zz5BCLi4)Av$#7+DlwzD`E3xmbZL0TXxKo57B?@DVGEEm0#{0zgwpEUNZ(C(F^TQ4C zyNvKl1F&%j-_$zfczI z`5a0yGxO!xvo~idrUX61PFJYm!|z}Z;BL@=f^GIFy@8xI66G zlVcq=&R<&{9a5x+fjq|>|n)T(u z>M!T-j$!9@m7X~qHWXLV(MqanmAw=(9eHDrFHaKf^*Dc5j794>)=b8+3I|guOT~lt zaFS%#Rtg_QYs7KK@78$_-Z_7-ufMJe^R^^eWYqhHngHIGw3Mly>%svmPbVJ>{dM+% z;r(?oPy_vSNFZUHT@8Vh_{Vv9ZuK}_b((>&`upof;JVQRH6$X4Z3sUf`|Dh&oAcLk z_18@&mCTyPdH>L^)v6u1-pbM81<{)W4%8lIgi$I0saI$w|T&rzTU z{yF1f8rm5r&Pq2{y${S4rzJfEm;(B^at=B1(d8X--t|R?8+v$Shn#n?@fC5%IUn8b zI^t-6Sr1$xo^m zl}lz~Z4k_b-lB3*-gTn#MHQ6`D21q8>?tZ2OwAmB4Nd7^SoIAb6x=M3LdQF&%xiAqYtzM>NH zu%D>phUr*TwmmDfqVkjxm2Dk>cc`coIlWbMTBX(ewu)kmF&3-q#oVs&$YQlAuRCe^ zR#6no4U|G!ZWd#U)rP5xR$?qxujnAT z0FzzKI{~Zxwk%fEJ49*XT*<~M#)5#2tFO7fr>Q5<88KR|31J1yW-X%1D>~pkaXB3d zPI)qcaxBXS%CQWmGZvGR#RSX(QGL3p2yO>k1}#X-YQBu2WXFrkq6OhdJswww$ZN-J zP;2b7M;KVlY}^w}QYOmXP8h9LJiTTn9Q`ua9M;~74&@FTtt5J{k1bfhH_1Za))8K?73O>)97LNs+md)!(Y+K%=?a4`2NV`BL4`#ol1Mm)o;Sz(q7*48Aln0SuqhW(W*FgJuk84R6Plw6zjr z4L=o0#KP|8NKEe-7>=F@44)OM3OLPdM3Scma2mkeT@FeCoOYbXfou!I5u6co8ux@A zBCta+d@FGjZ+X^FDGL8d(H?gggv-{BO|-%3Qp#CA6$ZS0dQiOEhP>?f%HJcu&DK!} zw(`k1CBxI+#rEH!j|>%*rUnup0<%`Y@fpa4;9TmEJozz|LeVfQ(`a8 z{>`R?(suu5lzMy(tqo2)`M5L_4SFc~+ab@X*^N{Mvyti$kFZoFZ6&VaNvWctWBE5@ z{~M_ARuYMF8n@ZWaKkc-Wtg2}cd0uuY`_GaY(G=l8otjCEj@?ywi7ImL zHOW*NoPH8jF!bps19YE z&>ph^3lRoG+ku!Fi_1_0BW=njuI>#R(5GJmqtp##D944F2#pd%8Ut;^;kf*mEk72Q zKVZurh|3?e=+o3%{P zE%0rw8c=sXfyOOCl8^i-cR%s84s3(^7`9XDH|;VVK&Yr7cff$e$m&9KX-zrmFvXZf zk_=cRLEiI-?$M;-=$@aKF5QnViQTN@Su!N6XaSi@)+ay{%&C~Al2(w0CydoLjuWZM zHZZr;hS~qsFID=U?F%EHSZdBZ(8m9gv6ri*!ZU@>7xDk^my&Fu@Dr1%-j!{Y6Gi2P z_TN@vD#a;^||vA-1q@GDGfRUWcuT5TOk8f!Dvk|!d<%Ox?2Docik&V$MJIlsvoEJ(9h!QD6wU*&>I#+qN#zhT+?63iFYCzfFI^`DlYucG{qb586! z27h>lHQWF2F~Jm*si0A50g44P+gEIyV@lM%HG982z5kQU;qH8U+U&HV}TNXPta z&P@N3d@LFGXL(lQOspS8XAxl`0 z98dmF{yK?Y2{_pFb7)-0v<~~{F*5q;j90p4q-;N&{onH0vIFU3!G|&6=&gQO_*(ek z^oAccbAbj+6WGs*6f#}DVCEpYenZ+ao;~+V=uY#G(G8Fh2C9&iWc?>30HFdIkLDkf zm5q)4;ZYG0rDswrA~utsm@GZONlNV8hJQi4fAQPTd~Oop`QubN@QLE|@BZtANSbtw z(SNTSeSELz2jM=9{_*7JpGN~Z-YLeL1+%_@^K(3D`vUyhVu#%PduNhA+^zf72Hn z720}<1&^Y4fF_TokD+$vSnU)~rXNIG$OB505u0DY@M`0d=C?T3tr8@!mcW`{BVCVV z8_D0B0ePb)_>ZRNN0q}SWGLx0sFWOp4dE!H%q~_qo=z#l1hXq-Cph(bv&G*Z@c4U* zzdz{jgMA`_*~j%|Fjr};E@`dcu^A2&zk^;(x4-^p7)k!>KqkvKYORs1FryQ~+Bgxq zKS|aQ*s)|2mmg@I+}C|cQiRq^`f>Szr6-9J_=7peAsE2n^gER093D{gDEc6RWD=YV zKS*mz*|KYyiv|Nnu1B33?Pi8uOV*ed^cqrmbEl8#N1;|DO2PfyCJqE%X0%}U$u_hGyFw~j7A1LLp@ zgrAb7ET59YzR*qgsm#lBJXOi@+y`f-AzRv(zk&`7uNj^N19KI>HVIb!SqymXvst_S zcJ)5Og4O4Qa!2Sy&}4k!^94V<(G`p*pM@!)$;* zj}hUtN7!_Hn#&jqO3fEBSO7R zxCGanqeNLg(#&oy5s7K(fHL}>7t_$5_A9w#37JWS01qa$O7)8hy)x@6^dIrw0Dxq-?CI1^g#)zFNRnmXSUsM}pWUNY1 z1U#9nwL}@f!HJ5k`QfI*VMuc`l4y$xbBg*L>Xt`Z*2s~-j)O-Yv%iZ|Xj@e^4K#(S zMO9S`QJK)->5C#2s}b(6axPDyk7x?}fbWWVrwVeN{yO_EIHO9mBqkt191hbfk}pzu zQ2IDDCi85O182ZqbA-+H`BI@`iEA|?E@*ruLr(Z4v{O%7BquaTNUNr#m4K|g!l#FZ zkz!UXJyfVDpkUP(C<(3k0#*3d-ORPHnT*P?Rro%HVTK|loiqv`3=T%y!?1I*q3Tts zIMj3kDyr&LjH*}B`Kai8RJejf)2a~1SyivXu@6+e3T8&ut8v*>Ko0orRK1E2!1440 zoVbd%@B@JfvI5#rO|KHoc*Sda%sClodU=AAM0o-?g&JcWuk1(_I-XPbWHosm594V0 zo=lGAd!ib!)lRD_5;i*$3c%-AM+zgBROVpyHYN=ydcbovWi9q!Od7Siz_uwOXGrY_>%5u{^h=JlESnj;bA`nY{c={eOajR zc=DDn(53Q*FTn7;Zhw`g>7iYP{_!DBlDp)s}=Z-_xo!e-WR;n^Wl%Fv;W3lM`yq z2BqPy*y`VfiW%L2bG^YPM8~2!@x;mE(^}~#kg2l#6ItPJiGIPhm9x~>{0W$QQS&F6 zUl4zvo*ZeFXR`nFox+bM9Qt%-qN4Tu_@vAso_R`}S@Sak?*Y9H(2v9jZx~Q8@Y3uN z_>0xQFp5TV@q1Gd>{cwXrlK+BANW2^Mdj(&L_-CklAps=M^ll`9D7_A{sF!)SvO3g zOeRuCbznyNgkd7V6JR6J6QLQX?3qK^@sBc@3z#B5c*0#l{EV`!hVuk16OnIX;zG%0 z=+&_cG_aJDZ1PAf*`z42I(b79W<`uLBal{h!8tBtmYbrh?&VgZm&S1!T9>VG;&QRq zb3Y5}%}%13@LXgs{sMnJKZ}2xuaTkyt3DZ+d26*+EId<&kIrDGP0y<=dqT^*7*uMk z+@=IxkB+5c*pyNXg>UNKLiN>dX)X}*LeX-jB@`2<^af*emOY5uu#CUU+{D(8EeqG-})@GrghwG>zz% zpRzP98tAeOqPxa@yA2~E-DFO=!4Edu*pLzAQ_5aW?99mGfCUbNQG$oh7OM$S;BE;p z3->sUYDTQc!=^|U2q-Z90KNgbF*Z5SlCjBwzT^cW2hf)cI%fugJoC(@2V=npHZ6l1 z`))HG@$MXY{EN!EfHxsBwx@&P9q4x$A_xoX?l002E2B19RwugWRJ__5Xgvo-%wg;2 z@k6GdNY3ogH3uFdv8t`cr4eU>5_t#spN$Xh5P5zI!XH{5uIQM23eRAitgxkm1R;+< zM<+*fFuhaf>aJwidhv9tH%v#RPje;(rW5N^_Elv1C2WB|u-K^M=^d(P$I}n#JEA{; z)O>@7fak^5C?xA7v`(l#GJR&6vL6CzyBG$>e*>xgf(5cx=lLhTfWvS+`LZui#rkW$ zpe0ZIGhZ-;f`^meWdRXUkpMuZ?l-{!7eMGTbtIr*>N0qaOv8ZaQm7Zilt`+;YN#Y5 zxZ`+o(SAkV8HUkKr2(}VadpbS#MRne%3_xf6h8` zLbnJS#2M!_v`c2{1!09#FRWBFG)z4sG|b$Ox*6uuCshdPVD87aheJyaT@c{z;puW!y7r%3AK2RtTUZdAuL(oOea*} zS>Q}3RhgROi8GzRXwcJif{CPnTSByN&UR8~_mhc6U^@Wv#CQeXmCqB`EVfMOGfJf#R)o`R0zJmXv%#=6H=U}Sq5Lb}|` z@}SxT)M7G~exQdFx)=r=iJUeHgop-vO>S(jX??ZVeXMd}J^$+7wE9fR#*%a*@G&*R zHHO7O7GfI;ygfjBwjDDWgej*9-fSE{aIl=ohz zYzWsZ7V5{bP;X|&U+y>K5n_Y}0-+#_G>2d-MrruCTdPGA(j?(xsy)QQY-JFF6rj=@ zLEgl=<-u71f;+!%jbP~JvVG?+=CL<3b^p5G)ET4zcMNF5vsXJY4umL5@m#iOB!hcE z5y>qxTe4bO(k4b7h3Dekpd6lrfqvBC5jb6!F1iBRnI1q&51r z$qGZipf9@6FI=0@FWhpWUl3;xYD`=aMke%CP2z~02dGe&2ikFh!J06Tiu4CMXhC2+ z$To;D)j%YC8h57BrGi#bCcd^+;7%MNDDccdDh5JDE-F}(i&#s9--5q5dmtx35?2IB zR&>A7mYyKY*onP2N*+}Ijd5E={u}=w>T_6)UVUeO!ViqAwLihDulxvVg)##*L5XqS zaw>C2tx!UzU{s>}stF1@)hE^7WTMt!Z<5C(l1(%&u{W8}Co&@${BIOw#-t-U@?HJK zcWN_DF>UVb7$xBt;fEh1j!?&%zTiX-Jb=+P<(GxAA-oNr55m>n9spxQ1DXM}^rrQ4 zGox`mFzot1z_6kffde=UOZQuE3`>m&cgT0qa$H(;%VkFl3xgRiVbFLYtBLyy^irD~ z;gSu_Xv}5IJ4CUSz7STnON0iMh{rzVq+{Ne_Jk9Qc?jFz(;Z7ob~La0sU8oGWc3jb zVL6Q!9(^CkD{ol)mNi#d!`dJC0yV1qkuNwRR+cNaK+I;u9Mjx5w+TzJfS(GkoOHtFlLtF(`QP>&ve^MJ@f;*N_t?+Z*sX@Q0Ma`f#atp%%>P zi^Slt2i^$1&<7D9nAYfY`ExJ`k7}@fF*A})qRCXUiTf8316J}#9-fu>Thrv<<6W_B#2n3(YTbpP?Bvjm-xUQnt}EremqW`2wM=lr(oV zJYNwTCJB6e66lNL%MCHCN6dsK79UV_OhG9SXkD*h12PeGq9}&2Sj^^bu**?*%Gl2A zq!REmc;oh<`vVrbD~Oflg7_Odo1Dw39?<=P6pODnbl3RJF6a&zUcx8{x9J7l1E?<0 zz1x}^<8}>1=x;pj!m((v^&1b5+qqTP;dcB8=o~{I;!1)8i#@~g0B>Tq&;EhYW50WU ze!q0TIiot82s!~o_dF!2{ ztcd+j2fGptb|t5*ln#^?fIpZ-G>|n=qQ`DZS*e7|3VsC23Wh#ZO8O})VfnsQTn^0k z&Ny%Fi92n!-wVZMN6q%n{xWPo+}LH!_RskOHQPV$3)F1?tF~bOo9(v?toAPwHfH-> zoUT1Z!ozBs2T1q;2@mb)kC5;?-)#RC^5Fxsy@qVSI8Xd|V78YurY_v(=FIj7=$FwB zdmVVaLq_}C5VW$JhQ$N)E1^cvgSTx5wm~bqIbFBS4!p-^`#nLw2SFI*bC*lR41 ztZt0-LTHG~U+^Itf`Z@@7lNJm?aGWUV=yQ+xO{G~vl3nzkJ#h$ZEg+aSw@g(74jW-nqn7!Vgyqa2Zc2oQlk0qpD+wI?c=9HH(eru3=6+YI zkA?%goIub@`dogk6!N22?!Fs85YVr5$I`XU z+|{pU498d5F3{#blhz>HS2SM*KOAxxj2({Oh=$|WdJl)ji|83JI3)qZA^%{Vxc#$o zhKIvRK{r-L3uT9skjkTMmLYcMz#5#I1GLJr55n$?D>K7La1ZIZ06 zpdoD5L(5(`` zBqNz50z|VN-@s3Sc`fAP#imUTAhX%w*QdDSMDBtc$}ER3F%zClc2LN-m^7`!k6<)8 zurN@|!Av?g_*6?O?+Bxn6r~t*)PYT){8sb#ICXmY*Stjcblyj0x{-ek8^h4c8jj^G zd=wj5kZ_HEIPan$;Y#-9WG|k@lx9bpTdam#UW8U8kZNKi`vC_h^i(K0_X?-Rk#z|n z6|?sW`u;OkLq^C1+~ka}`2qzxulfRV(&Nd?z5u^ovcH5ieHE=)mqV9~BAFXJrTf*T2!kn4>DHHG0(R%(17BcctXEV9 z!E&Yt!vVqA%1D?^MpNk4RPu|zf_ER4kx=~hk5~{6%@=%u4$XIL-(^od2ID{a0{r@a z>@PWP>qQJrM^a>pY?C$1F_YCRtP2DVe8AP1HUc^3A5XZy5pf=%glS~;Y`0`zl$=2}_M1F!?fX&KPOz3; zO2_mG)cSy{)noNvw$oy<`j>ox&eKa^t z$U?BLImym|fg%thj1NM)@(5_vATrS?h0#c=S1_8QbBAsWBJ-L&?YlT@kn;%mSC-Z4b!Ev`WYTz|nA{N_hsvh;-K-Q-9D`7>^TjM!C2b++i~oUuAkXAr zn4%#i$z}>GFHR{^37w)Nnj`}}idjlkh~sWS&%Fcp#}(RP30qF7M59^-BW&ex2J9`< zV;Uukad2+|qRijJP4T z@!FRuL9wcEiOzW5j}g;S6$(GE(nNhI=JU;<*9ZKU%Op@76T%toez zCoQ}{$&Ughcf2Y>)F%}tSy+7lk4dIjBU^1cS?nAQAJMghnvmcT{9J4u`o-WWT^wuy zj{e}+%*rU~%D|ryIp)l*42%>{k0WqO_4F`HYhqpqX)PG2fX)&}XSnio#;mvGTJPO2?R=_O7@GWOT0 z=Z@>~`Gs*(f5Hq1p=G{IDJDV_tggcXvN}mokJ+9!8U4ZPWMaYU*l5G*?A&Y8YC{X? zXTZyJ-m&3VlFaD5laGMtgye$RB&d_G1QRN${4?`a{0;FyJetBN;{l}v)iJhsK&w}V ziMf^*kbNmv0@n<3nsYgTmL5<3ZuZ8{V_32u!P|cdf_*_)-Amzg{AJNA>e0Yw4?Cg6 zwFnMIu!o_4H6D6kD__tQDD}E8P{H(uFKEdVZ~1~Bl!EWt0yllsq&8tyy7}o7e#jl$ zW&-hBb|2qh3V%nWl`KyKW|cqH0AvyxA&DfWFg-Y_P4{;{fG%)CxDTA{lvhYADxW1P znx<^)n4c%i#7bHuyu~vfbh?>0Qn2975lx0;j!~6vNtYDXjy5=zMxyqg?;q(i-#`6A zwA79#Kj#Z{zJJLV=zRaGFVOk^bzkrUGT-NIft&B&!WgX|%(qt>Zp0)8%r~df%=bSn z_gUZR6WRNs8Q0Z)!A^`aR^)8<1v=Z8e1XpPWnb_fncV-~7P!g%4NUH;0UB6_IO|76 z$Y5>^f5xry6WLqqzdOIRsCb0<<0{(N3iwf--%Kr^`oJ>jB~fJBIOwZmEkql-z<5z9#1hYDhI>pZu4{~ zya8v6Mam%ccey!~*jm|wd&QEe^#@<|1xo7Id;v-Q;p9ygxUA?;L*MxojQs+#JADG5 zl;}ptWT#GHOd-f6tt^`3v4dpWLdN4K@KU#5jysg?(ZMcTx$p&-ryjqag5Jzla&T?3 z@+T;Jy3@m2bxrcr2PiPMx;A}ByY*j-&IK=nyy=baSfXe(#wltW3{X*H6LgEtY%9<&CsgEkx+$` zGGmf=87IlRj$5aE!Lh*P$vyN2hZn|ey1&+C#a8wPzMLqSW+B5&7PnR}^uV9t4eF&3i@@OU`Rx_tH$t|=)jLdAd zSsprgSRTwN?({j5vow?o2laBid07WB$UUkWv{!Oqcuj?Cp#a)JYoBC>Z*WFh9joMM zIDhF|9Dlhf_!qCeN+QiF z*&oZ_Qu8Gac9uHgP_J*R`cQI+#xWeE_)sz~XC_+v7-=; z3ANAj3O;6aTvGc{^@q^?h6a96GQ0LBBh$x3t1y}6zr_0pV&*f@SHrxF_4V}fJ7 zBnN&f;J{eXpU+Kza3^T2RtmwGDKo_}PcVq14Uh8MtuY#Hd3K3A`c7_f zvA7RyenI$~oLELaiF+6>&vt}Ke)1$T1LMwP#H5ZRa%fRPMoZ#oC|j&)C{RtOrKW61 zem#ZQ8w)vVgp^ouv%(~6)T}L&s*yyNb>hC9mXC9)jR@_^&P93=}Er2)f3sW3d02K)}C!tYQTusf7uNsoo>?lIa8IY#&g zx4-fwa=TKtsDBN&gKP|D&(ft*Ad;?n+8iTkf!gdjByNU5f5Q5lb*h@Z2G&JU&9%w0&`cYTR^&Z1?qPfDB zh4mp-9mYi)h#Qul3B8B>4AETvDa+5~sT@DcJ*fQ5JQ(q_+=I%`%!3g>^ABQr0gW7{ z1Omi7AIo0kJUhReEqyjDZGP=pEI))QvNFp9NfGwizV&?g*3Xu_wUc^ISw9Vq<^ZW+ z1YLskcSAERPeZs0Hhm1&;Ed|`J~5MhQ|NIt`?mZwQaF7g^OQ+EEweyVa)~54GbtY0 z7W}Xjq`(?P9t5jRajp}{(aF0Gh9*8<{L|Ecvoi4M39wSnf9nlKw#V8`MaY=6*|^0Ua6*1g*1#B$CS#lJUxTOSwF#gk&Dn zp7efD3CTRDge1O=wB>6=`$FZ!PX5c`Zn?P7T;Z_?cqk>? z0~yFGH0gMHY+@V*C#7X*arR%&JS=Ub-hpPB#(?xCt*Equ@hsz%pXFBFH3sH>$QB-I zD>*EV0X~#}0#P@|{zo}%S2Sv1WcGHVR^;fFjXzRvaS8Vfd;!Vuo<0SuR?i1fnKl`iqHhAAsKV3BSM08t18k(RnHNfxst5{ff5?IPlw1rl+t{;{%)a|KHm z%T!s-4uSCk+>koc#vhrJ!PiBtngsXd3m(WIxX_$HDuH)a!2&`efC4^)f;B>}nLm6~ z^xhseUGeUUP1kBsV$-Do->mowrc=QcEH$~~N1;*UU|K21zKSnknYB3YJnl=6Htcm` zkic~{KY>29*-pD62-6~`S`nvdk<+Wh8YcZ!K93gAhtwJ&UgHlo7@JYZugcl;oDg8_ zCHd=ptLc2o39Z~f(=s15KAkFp%scSZ2NSu zJ!1}ZTQqdbXeNxvWXXUu{%k^g2bk^20JA-YYXR^Q`qVPPKA`1?!FHWlm2(DKcK&wj zrf~jtbpQaoS?4*9?g5WHo;ZIy>4XK&-(Jab{&oQi0O-@!-_Fo17~WuSQN%Cic9JkH z){&W3ycjgaehPQcVN3XcRVTCrZ{55zLky|gcV>J-i5-Ro=|{L`tYM+z4GZ3zK`~1T z6|cl|tiF*=zE*p>_k1unp7^%H+-n z4F?W#`_bD01Gpng(uX0%KSz8Zh`fWG=CH9l&S_vf%n9cfpJnQYyMN-=Fn4{ zXki?aX~G;1j>TOV2qS;tNG_}xeU>uw>P92OD?Xr&9C27_qu1S%M3BF3#4At zh3}MnaL5TS%~G(Ui4y79|A$2&bCUi2nek>)D5e$tUm1T&aIBTGvkRSel9>%V*qS2@ zkz5TbJm?SE^br7l7uQ1q1}U2XcxE)N>U3a~TQpCYfv!W1EoEPk8to=5tYA}Fwxpjj zl{W99*(ymGi(krqPwv@WV&E8j>9Q1#1TAqd!QNiV{z&dO%(fzg>c-7JeAgHB3n?G| zQ+fDZ=3$*qz5z2oJE|%&$j zmrL1o`QUwaD-?J`_6z4Y*ro_D)ed&94Su{ad(GF`39_8vY2RMkNx7@ff^lqHqX<@2 zm!5;FPgvUf_xBVjzuYcC!YL!dKx^Q59MQ>Q_ClLI4aaq|;6~Qdr(W^&p%dI<0=YDm zK9&_f(m;39Y#ki-|7Y)g;OsiCI?wm7|ET+Q>*}8^|B3zj*@;`W6e~=SgOh-+NSv^< z3?>t1JUg)K-OcW18g@7Km~3V@Bpo6W1q@Mk0w}X#P{5lg#DJLbfC2_O#DIXn2yhsY z(SWk+@DX4@0W%25B=h~9Q&qR_>-V}_QcIRRwm<53Z{50etIq#(>QognTkY~2l(-k8 z=&d*@dN0Npu;OF{dodPG(;s*M0$q=`GrRVF$_vW|F#ElwP#7w)-2X!iz|>-?wRK$X zGz~eAx!toXdZ!p#P@9kLr&2Giq2P*?Az!noV!~3n8ue6A275nLAhJ~w^@K+M2GQ9B zT$RKZtK{rm{*cnFx|X+~@4i9-slKh_uz~i*I3toghaa`hsCn!^e%@F_DUmm=jILEgRs8PO^4h{*V6&l=J`TA*G2l)hQ+TF!0=;vgaOFEtUT9Dtf}J&t2A4p7IK6vL1FY@iAe^t*@UeO z6D%brO_d_Vsmq=YNfmABu{(yisj{OzPy8dx-A01W(JvIyCm#iDuE|_a{aRJvn(Vi$ z0tH3yZ2Wr__!IzU?_r@MCT~9?oDkb|h=(W(;6s+tt*M@(_ttF@wu&~G72zWRbbBS8 zExx_|t~Tjmj@lRxB?Mte7Z3#qDV%A~wTjy=X@#P+avMiy{N5XU?rpG=Gb*=)hJ2npGEFs?8+^Y~O13reij$ zXjOWQW$#h~)HCuWKx#7~8dP$f{0W3YmRqgzyu!y0l@u`b$_8IkH)=W1VO!V{k%e!K zVv>rDR$vnA2_S2TL2NR@ZeWm*cg_=-qhcLY-c-_efR$w5#25&~T5t$2e%Q)!Irno7 zt8BRlVF`LU_RySIZ0o{YqmAI}HT1e!4~_DzW{CtdD8)H(!NKmFuya31V0PUi2XnU6 zy$xd2f|(Z<$ZGS6a7#xgD^tq5L7msaWd0UmBW`FvS~ag-e~DK7s#zjAGHa*`&o8Ys zyZVv#>Vz~<{c7Ui71CaP1xaeH+)sW;50XVv|6nDDT~dFfDsV~t<5huAU;R{7&_f{2 zH-26Pa%4!;38MQES;fqDKQFqkBGH|s!3e>fOM~adwhZYcw(m(20I|(YCIPV3%n*&n z+3DuO>P9GwHU@Z=sXnZvKarK`YZzg?KhzzJR~}-&l)&1ktGS?;F$*U4*+zTBu7?F;C-diZLU%%CH!w%8Q>3+QIS*WPQ|?LwxK;20Owvir=X833?Hq$;>ITZ$t8e ztQBTj+}23GV>CWeG&kBXX-3xzu$%_06ecZ{r@oyWK{7>lw70t*WuGv^HdqR>(|DJn zl&lu5A@`>1=1m>^eMF^${|6-L68Jw5!KLK;6DD*F=%po>acAtukly#CC2{2#B3GB7WvuOU*gr zioy!*$3C;GUpbz58f#n&po;CstRTiNjnxZ?E5|m z8G`5%GS541D>`n=+%_QQ^0elm;Xw|%Y@y;Zhi!FvMk08SXKPX?FAQI@h(e`K)*{bp zo?((#tEiKjIMaIJ7IM8Td`psA2+d zCMqjUQplQw$PfK{wli`}?>`+Z30iQHYg`!n8%|JwLB~7C)4Qd*dCCr$n$>VBQzbE>t zq-n52xykI%S6#dvdRrpT)ddHUlKF}}o6!(rpWU^Prwa}@bAEof6>0(3B0dyiiFpmN zL0Mrb;W21~5(JAvB1l>(tBPjwNZQmgJCwEWUOCB!b+AMca7oAqYiuyoR%hE7y>Yfx z-|GgVKQ|lA7Ea2#S{8>+!8C>0Dr1c>TQv8cgBDqt_ymirtXX8`6=adsW{zzc*N(=| z$p^?SvR|qSJYw@3Re?urey1u>#AZk1_o@OV9M3mCr-FJ2=VP$lQL;dvH{wY~*#l!?|Pr|Jh6S%BKoF$vD#Vuujz!WiXjcwApG7}KaiW#V2nI*@BP@1p^wwy_8 zRZh}+MQe_*MVw4IZ+p&r6@Xon)%VUy|3@ zHQZ!&&AzCLW1>dX;;Tp5YREb$5lGs(*%b*{!vh>ndi5-gvGQ0J1sNIZI8s%5?gcu& zDxnFr`c*Zx`c*;`Qw)TbI-Y~;^RseAZKheSnV4PPUW}ExId+~C*~*^6;)~4(0TCv$ ztrNaqZ@D#(cSxS18J|+*E!VD3R|V3p^NnXzP*;`jhp(4bjd#f4lxvmp|7`zzZY8l& zhY5aN^nA60kNN5~&Qw>^(aUD4r$WcpZKgVjR_7s$1qjVD-q#%R;C!QevKyL8B7cP8 zd`?&c!8N3UWU(k`Fg_4H)d2>B^`e;*O{r=%Xb79F%2z*bd^KPGJNpfb=g`hO z^OTLjDS?WW;H!%LR_Cj@2|0|#CgjgS&U$6eS+A^d)+@zXZUT?cp!Kwz;wLTlRQV}^ z0#YK7oevZ_C`eMRPz&`uKn9c9#>YM_WOquBzxt)uD{>gWq6XtvXh{vqe367K8}U3U zUxtLB2;A@uSbLNBjD=;exzm`P=shc3rQ(4(aI*)-c7 z1a=VDD~ooM}z;>wRGlIId1ei^oLz-??C@CR|@ z0F$wnEyp{w9>lF>yJ3pSaFlMTYX&cqzLAR9P|p_}sUpNcj7QEvo+%h}8Iz!QGmLCS z)kcELbM{xs1drK>`St-y6ZGu^hMmgT)QLFR41D5rB@WgssoWe(u}G6TNs3^f*VRU@ zVb0qw+i!Z~w$f(2>t0u-7|+H*5vTdEyL{>dD7$L;R6RUIWEIs92x-ga=NC6(n(t$4(m`P0P{2lB#=jAN7G0k4DA-@OB~f~Eth0`9|@PZH)hzas%nksVX{HqZqb627!2YRX0g-l z3&l^%KqTYYJ(Rfo5hlC4Ve;aDM!ScTf9NJ^^;J}SQefC4%HRe@--8`)*T|MVEp3bJ zUqO?G<&aK)*>3v~lA_KgS+)lKY5Sge2A59^6aUpVZ?<8bju@F#*J--qWoglv4L=dH zkp}3wn)HI`tGFq=nm9l{f2CW*khMh{V$`eOp1Uh2@w;jyewXaIo@|~uZEt5&_;ZTC zn@9=!;^}Eb*#$&do7(22Rl+fV($eXbKku2yOcTGzw$x>PlI=*&27FO|yQ$gN=B_~^ zMqiqJbQL#by0>~1=1!q>Oajq7M7omUX0yU!Q{A}GBT9K9eKk|9^5)|%y2H#YGu6U- zkX5)s{!h8M$3(;I3s#-%)3`bLMA|=hFlLv`J*WP)8Ez>SW*j5^V{kyN8xKhA*pu9F ziyP}kE?adb`u9vQHp}oE<~B?xRcr?oYHXLnW-@_mhFdb}auyEUH*&M?tK6d7le6WX z8e8re#g?}kt6nTK!hdULM)!)CLo=4EaiiN=Vn%rqb!H4K7*Z!z@uF5@#+9Sk6>COr ziV?QTeX5vNV-Z!+Omi37j^2;+u-(5p`R-rXGu1+!TX62=+GBnxk8dwqPqCwTJifyoy|$9@ z!J12pB;_5*cv85*1iuPk)~f$Wwdx6C*;Eu9;z|QssUC$M)4_TtB!Fb;+0lAdvp6Pe zQ69tL<_vRrx_Sh*GE0)C!)c;nHEx{YTiKtK!I#WZnV^s8yTJxEqgcC&!p}GAdl?AKwTe$#|ASLCkkIbDe?jxTZnP@MBJWGkm4zEu@`BFc z+KsIa{>VC%Ei!pYPOUGgQR_<-0XVCKOgCX1c^5og;+aitR9s-X`;rk+ja&kO z82^r-kQjV1PZ_ruha?h3omfVaNVP=TcrM~F$E}22h4mUe)F@>c9X&Uk!aH+9xU)tG zcP=9YwkoJ*UQctArd`>lfGrjfRhkfyhDmd-%WUJQ^Y~5N;1bGDjBJsK?i@*+@ZWG*#ZXXyxN{2NGY$B879kw6%wzCZ#_38*RGuSch!i0mn4@2 z&xOrll(UJDA^RR=KMo=9X#7GXT_gL)<6R6?iC8NY7vhv=Csnc7NZ4|g&54iJQ&5K% zw~{Hihm0R0lztBJ=jAr5QJ|`psolP0>Q)5o<7Ab#_?1lfCW?v0aMOzb`t99bYAIu+7I=~R%%KKlaw;gbD!1m%h5 zOrIAd-+e4~C_ZUWuzJc57VhlZPj8fkqA?R7fUk#+IbuAhs8Js7Qk9r2@sOu8kMT*_W1M_y zoAFe<>cfDGdzHs&@5njxjv8m)APt%IX=37rT zeFG!7BDNV-2 z{_JTf5$hlWQ7b79#uMKG7YLcTNsY=7_njGR(=rRDV9?v)<$+9m+<#@1LjY@sPRitu z@{F8tyE|}0;w(8Z0v1tw>257P2>tg-@wfODbK-CED=Z`pY0)}70zHe8sy-xYRCX9Q z!N}6gwcx{F0Osx4)HrVyKV`|25YpaP&%BUlFI5F9GY(MFAD0zxX9|0%VYKh3ehF13 z7ggO*+TUo^LklJ<`)mq)BalbwSzDHpY42MiroCY4mtpf@V@`+q9|-EAHchx#XYQTp zm$l6sdS!$31k1NMR4w(BQ?{dVxGL}s96lTiEWWJJZrZ>>+mtXI{(v-(DR+rSXCLl4 zJaIN>O$L%qASpN(U`r3n(Yx}mRwGIFcB*%t4294hATl=%U@z=8jrXzj*H0ps)KpHlt5p_p!7vQ|TvSWw(A~a=F5Y_~Q+2n#=nqgRsT63Fu#YerYZ-ySGW` zu<(e#;wziK_kF|7rU=Db@_~4H)k-7Z z9{E74iC1k_i=tvBqHyV&{Ec+2yuMJ!%!*;xV#{IeNJGSOdE4>bXiQ@?nA0msk^GUz z-z!SF1DX|WowK|5%l#-$1%S(A8EooQy(u@!hc$Ji)|6N}_E1Jsyw0!^nCGkrx4iBW zSy0-f-kJ2rB%#Y9>?S=Zk<0cRCkJ@VJnW&E?S@ry(MGP8k%y=q&R!uQW}%8;kdS&4 zM4Odz6LyM4Mu$CN4@>Y$8a0;B{R|}Bgk0v{#E6w@uxb^Jkd;z}FwmUl;UUv3@urGr z?6fE6xr`>BU>)2eb${N>HxmW5fCQbY<_+l7l#Dc0Q-_AmG(0yV6l}?lJtHN|B3y1V z@yA|bW}=#2spP*2(zNW;2?nNql~j=eUi?h*q8uovnBNyCmI_U9Aj&7ryd34PRtC0V z2&A~Ll!cK*Fh;g+SX;d{c&x+xgk~B$(HZuV&&F=Yz+B}nuI!Z*d}`#wv#s=*OBLEt z=c;H1j&Ea|!9mjEWwDyT_0mWx+&l-sg&CO5#jiKO)LsG@HxVt#r`w)v?Q6Ua5@<))t6kCtgwwYJaFE3DI6_rvoA^|r-eo_y_M#Z4U7l+# z^c#|yb~K?{AW=b?0USivE}vS)7<{c@7agMPVz%lG@`6qkqmQl}?< z&@a1Oh9TbDx8tPmD}KmC3Zp&Q(hm9hkPe1;+P^ug-SZoB8!36pOE{)>zID1aX9q%^ zYO&EX-ESM%?(c8X!#5T`6hLj?($nIH&3W{%Xuvoi82S#Z-3$HAa#Oa*ImCtm;CEf^83oseXP5*x)SgjrV=wy#pM62k zyAxjFt2fyzM|5~zHLgc|q=H`m=5pITIwwo%(sYvx2bqMt5Z*ck!p{k~^tJd4!CfbS zdDn3%jSOo2B0LgDQ!BT|MI|Xbk_gKBhjLw{BRY`TzPE%n@ot@a7uuxw)BVm0^n-Gq z7T>LLpuu#4d8nH5h^_5&On8WVa2P~!8i61AwILgUlW>I%q7|a)SU|TES40L_pZ+2Z zAkzqF20fy)ScMJ;AiJHuMVb@Fz`*q?3UmNeL{B&Ou1RB15oB~tAPoVogmkt?($PJn zbA9i|+AGlajlCDdA`Scqgm7GhaM0g)LH34vy7(1XFPe1zL4qzoP}NTxPF0^kJeZ>it#LW)A9$S0jedEI%fc@oSjOf-Wdb~cha99;W=`$W62Wj@^I}|y<7w$C*h9X*q+uI{W9RA(6}ZH7WEt6 zKBTL&yq-{3p5d;-?P=~RB%S20!p{lr5^D5SX1UwP)gnZ~-$Oi)a^$F8A4f|5Ta%Ik zwn(WP-M(u>fjRktG0?UeVK&r(u2*i2uW+Wg)z}#e`1Fp}6E<{dG0EwrrYSB&G0^ks zod^3eX5?-f3V4Q{--00XA`HtG1eq5hHDoU3MVOU3_bn9xW+Vp^K#h0(RKJ5JfF#M% zP=G##H>;KjjwDP~D}ls@ljJE)FCx24-U-Go*U&psWB?@HAjS7^9caOUx`uqZp=fWOWMmW_rs= z%n;xqNS#{I>}>?KbFH?BT{cWK)!%A1xTTnG$W2NSIYv!Wr&hoi)6>0KxpcESpTeBG zjeIJcPl4Jl558MKW$BP)P5Gz?U=C200x*}Q2BWjnm^qMC@gYUJ{4_Ei_z{PCFrmra zc(%s0N~Y|OQf;dG&}pD+uI`WV+!}y+5Gb6hdzV*9w61xk>P?{J)PN8B5x1#T6O&Vd zUNmLI<@QqF<-Y{hsg^YKl2oNAUj~FzJEfv_l@{M4+hwj5#oDB`2|;xpEPP^sX=0-= z<8bdY9}hdyH1cUcG;$~S6}{F*z2T;P zXy?@ajCQ{7uUiv3gsRKG$+x%Owk0|?r^m1Gqp0dG(&f7Ab#wsMLOlK|oqomPSKqXC z+cn_;tZ%&O=H6WYmVf-;{G`-|%1k-PixuU;Fp|{@306^{;#Tx4rfM`al2Ko4@s; zfBL|KTJZ`wg3$i>y|146rm{1~;)OX*vz_D6-nl9MP4lly`3%3a{M%Sga)#f3E9dnj z5~G^^(_L-$?<`ph``{9#GPFzSWt*21IgNpNMqK0y2Gjh1@g|K6BXf?h1h+&2BMd+IXOW+ z4~uF*l;S(qPREL2(X(v?m7kSmgJJ;Xf!~ody)nge4Ei^6_hdJHqb@R*g3rA(bC#~}u6{}cS`RsFRWPK+-U#{)c9 zBzrzv8}z6F0r&t04Jhwr8jvWl>iXC|=x(uhSLo&uTPsUM6}-^Rw#R_BuzG`SSF3peRBi%9MLaecM4_(B-WVqTjki80U#EP;8G_Z?p$WnyWdjD&RP3-mfIxbROAo z(B$4$9pt}S(<>TET~7P+0NTaMpVExAdvAkLw}GI7R~ihtovtDeF@l@|3vU`G2qLhB z-5Rh*hw&Xt7B&y5!iv*it6I!FOE3nat4EN2&T^seSgRE1H)AOJS#rz-s6kQ#B9636 zE(a1B);WAdpUDk_jNmG7epRQU+Td>u5#8?pe9=riXc+l;hs(Irrmx3*tLY&Yz~{pA zx?z+c2*x1LWR@iymVXrAlWxx-o8Bz{EY>g)kwKQs&db8e|C?CZ1VpCOFNT%VrcV_s z=ZowFDQD&3G5Pb02TOnu1A3m5UE|dhM@DZIMUGS*D{-=*T%V;mKW6@4*JCMf7Y7uQ ziWX?`QJcj0<|rqwxOti|3}K1k6EuVrE`bxitKf?UN2%k^idn^|8f-&(~nwDlW}y#iIR&&M)6}d!2jurMa4xA z@W*X{Z+Pww@L$;g|HtR<0FT-L|A*)90Dr;;_}?=?q<_eLCdo7y_U0xiv&{0{Mi}u* z<-*BPcrd1t#MF|F!MU*Xt&yoE3d0|97398I`Ht^ZTP=Um+N*j`kM%bx`M25Il#+j`ZC|04CX2YJb*`D>3G~UI zr*stgGXL(k)$)}0lFidKbScVsP{3IE!D`-D4|Zzm*Ah~Wj%)V>OAT6LLU{2<|G#j6 zp{j-47299UTO=W*%F0ufdg7i+$h`3gUrOR1E17Fn0Ea9X`x3zp>bMuSEEDFD8J}WS zTApRVgp3#=FO2=22HTO5yvmQT{1p*F-F4V_J}E4Ysb`w~LYUe_Ze2{%2GX0lqESmL zT!9uXtuQ#9vqsQy)RCgeYg9s8pw~#BcF$^~W?Uz)=lGhNa_5-uZcf=1P@JV7DnV8B z`$eOSexe^ozCTPPq{1p`sZIu~#ih=!P8<>IfjFwfPqI2K8{_~ReAIHEBIehO@d}|} zymAbo-%UBHwY1T4ahF9Czv+2N^Ix8%IrfVr*@^Iys3EUd`7BqcsQK@n7d0WGp)CN1 z>7i9c&Br6kl|pW*OP62P{9}2vHr0`ZJFA>BW=1erf))+}zorln_?t!wd}#xkAGRf& za{bLL_^c^~7bK^X#|XxOKenV{X&M!%~2tSS+m?)2zq0g!4QlJG*D(#sOOpC z5mn3ywvDQB`gt1_wREM*!a&7T%7@PeU5c>uRf2q$aP)K9|Dt__V0M6^L65xFD*#OSp zze<4f#IpgM*IgyR`K4zAIA1T|xDp*<0mMc7Ua$Dc&`U+-O<0Ag6D?xi9?M)y<1^b{ z-d@kOw3V@h*Vi_;8}eDHC2yg7&$=YgysGXxU7_+cnN%agD4E3Vg;l!6FFzY3^7lj{ zYw9nS*a#yrBO;lFMsmgRd^7_~w=g2JwOnQr3X_8-p*x$&bX-f$<-SWboS%PIhEq;! z7sn2MhHd63KV!Xcg(2jv1$_P5vogTF%LlkNdF9=wZt<(<*YU-S@-#nLvfB8(NbIXF zzRRDw%w7JjAVd~?_2M_w+wLo;%fI<8O%u;SO2zrCA`zVoY8|Jix=3((ie<|Jdxk1UaXp1kWh41(J!E;{Q3n8j z>1gpYf?D@w7sT_Is!xwwpYFP%`t-Bbr#)9xpMK8z#OdsAR-Zr1It_%^&ziuV()N7X zo6qL8iYLySOV+g3Y84iFsfOf|YJ@DylU#_aE(=FWmYERImny*M?mU)inGs1pilh7C zk_2WJYt`e?WX&Lvs+1#{T_+8k+tRd&xZ4(}Nmkj$X0*qwVqBATsM;X|b*NMo9n)%) zPrSh$efJ)OP2XIVIuHKeKe&XlZIypwA8pssHlR_f=|s(IM=@pTS7F8`m94>uRw9R| zE4@;eWRbCZ<|`FzjG0Rq1Kw|ls=HA9h*1<(&y3C70MJNFV`kb91G4WY)zwgT*To$P z^kwn@I}2aVPUa!g;=+i*1LGiB$A!WlzM)eGpxKsFnYw~DG~b@p!P{*~v&IQ=?8xzb zA|?^S_d7If;K=@rhJuDjgr+R46{sO7vP0D(#zbulIbqb?r!{N=n21DOs%`)Gk~&DU z#K^%>8xJ-Chp)EUq9J=4rC>A+j>gp&#j$L+cffdIDlwjL_etZ6R`I=(m=1ab99B>Q zuYul;3zw$w>T)zGm(aF{_d4Pavq@5R0m!XV&S2>rqn1KYOGLDg$CyGMYvA|u!LS6- zpsAv=`kYD1B^ZX}Xq*{AC!SP>EF>m^hUg<|FN(L+FK{tRiYLAqf?Dy&&K%-V$eJiN zq=19+=MDRvlvgV(hBQ>Y5U`l#h=9dF7|$|>l6YQ*q1|;h)V{L;h{M>BZ04GKFpT*I z-GljDh`9)H_uzsVRGerBMwhdRJB0uOh{?z|NvP66$10*kBT!H{3Sx*nsn&eus522Ih{T2BfRg-#A1I7 zq1`Q9z3tmRQZDU(<+l|7zjn9AFq#i0V#7@rq?*F(F(=P%F==hTTb+`LouD#%t`iR$ zT@IG5G5;_^8D##!>HQEJumpz90rZtwEkxAJ>Ji&bJbNJm^%;~EKP>~`DhLu7&H$^W zj6f-tK~fxZ^F^D%CYxF7KV*)sgSE^lzdAk+W6`YTVDyd(6$Sl|kR+ug*mKHpaTzdI zt%#B3Dj^}gQKOR4`(y;kvx(M*QEO%skbp|OyI2f{-GFM}ncORv6>%YoBu}Ms2JAFd z9cmM7a)kgDYjA6`+Hx=L_v}QsW*L6#UYfo-s5VqqR~uGoUK$IuggpG zMi^5V;U%>&0*>d3y{zCK8EoA<3iIS$MW{*os;iB>s|M=s-&v)<0jdF*3A&dCs&`gh zy)*A>_fGY42{}XbA!kf(0<$eC6m>GzsIemko;<;ms&N8G%i5@!fWby&lXqzrlPhdP z87+u;T<{qG3M{`hY75;HSF0^PFji$r+P1i2L6vZOt_d$CqlZ8VNO?g3ad&|ez};Nz zJUDl)hJz})bzx4Y#p{v^*M&=tj=4TuPA<&d(B3P4nDjZ-?wn5OWctWPTRijaGSDD_ zt#cdnQ_M~AL{S`pt9sm>1IB8k%jAavJ3do91Q|Bf+tBOwtdh0Y=}peJwr|4zW6sP@ zHyPX2IIBaOcz;*p^Ub>(C%Dp}&uKxa&IQmf_nK=lC@ecc0(G@t5AlXHFH$}!sf1sn z>+jZ=_Ou>Gt#L<4$BtFf^@%aA%{asw;9fS=qx-2{>cE-bmDcTZq|PRgT5#e$ux#Af z_^x-+^vfF!3L5i`ck6Bsch_+U?$3pImxqmdHvq0Ehv!>Q(La`{cKTE0jo-4+pWOE@ zYM;iQ1t5Or7w~u2zN>R>?rv=72bW;bVe4^PGyQ&=_S9qH+Mod z;8YsU?9lJ2jv?B8>fZLOj~w*X62Z50iWTtLLF`kJ5M+<0q=2!$DHxy9w*!oA8u5D^ z#x^Hqy&||v9q)U<15n`}iVQGr&rNdd6jEn1xWBeYhuT~dj-=vvAHl;MToUd*QrGBh z)TR7m&i~QaqxByky~)cQFd;I?871~<3nN5~=wvndy}cR6rC*LhfU^qtceZ>x3x{SJ z-J3WsX*H7}ME&a4oXCuij@I$QPBIFN1Obd`{C5Xq&(DhxxMDor<$*y$t`8$u2@+#t zFBos3NJJAM=ata6o8!RkEtYZ%rkqt&wKTsRNc(tfaar|FM-=!MierJ&0W&4)!LZXRWVWI_O7jFo^8#>X4?4J` zI7Tpy@C3mvGs3K{IV3du3w!tL}KPvJ3~#?6_nZ&eb^sM&Axi0>zo zO5r_h2d?DQrxBFWCWS3jx%K!m*FQO>3QeUB_a|trD%a9@ZovlP+me!XvS{e-!*RQ0@ci zUMpHK-bW>AHqNOcOu(7rY9xU97imVJ3QIn+L#4z}&EnDJNPO7j#xh|bN;i8$PioAe zCu@=i7y#$TA5fP$7`AuErpj%bmTaEyZL~kxbnCousP4E%Pa?yPNv(8Ug;7{Eh!f$A z;o0G=UK6I}bW{liJ!61&hO6JvenuC{0*>-0)<<3XS0#*OVpuee3~PFL$S@iMwRJCMtEY!g$9+WZav(VmLwW(BxVh9=$MqF z2`R=LgcKvJgtDNroS#fN%4fcK(rXMOy%Bmy3THU!T{=~?BI(^G(&JA?dbf=bAA$7t zqkuP8)O4BXPRcOR9ek0~-A_2(adK)~Ax|05_s&?X7~?bB+3tEJOG!Hq7#*CB2cloB{y2qf6y9}+WsNe{_GHf4AfATZh zb;uQ&6yzBW6qS`E38?7{_{;czzez+jRg-&P0H8`1fWK5Ne66wu)-3JnKtR40ZUGrh zxgZX@Ihb6Trd~Oayky%dg@d+mR53I2#2XE1x3(xs{(`_=KhVpEjcu{)=&!CF^R=Tj z?@&@jxU`j>`(@xqu^DxFt@pzSQAVS(oF(Lp3x2C*{YZ5B%W?P9e3xR!>1USX6wkJN zW&o!GE4?-RnE-T4B3YEGizF#73ah{WT*YeK-F`V%|9UxA z1;#4}t1rB0tbTC_Rz-G5ydp*lmug#wG2;^-FawaYvG}mYm?->ZjHwOV>RgS*Nx>^p zT&gr~jj!(bDDyQ{+ouYCm8(reDKcYcXfh?Zz}O3cxp(M~yf>v40UK zce-49pGxP-rMwi9o>#zI3T*CrJDr$QiP44x;O&&+F2B>^G~+3*b(--c;qNh-EeA1< zWXj{DjVTg)K)+K&l=X{)AXm9Jy{GjB$iCOz(>kYLqK41t7jxU9h`1FNMI^{!>>;wh zKBd-*Ikx*9BZ{$QTpR+9Wn)Lf4hp`j!OSJ7R>8sFVVGW^En;>w4pjv@b$7mTSOtna zTjWwv*nJ;_*p|rjvheKk_+g4vF4N8_S{cJJQEvymZmCha)~-+onk}5R-p1EhU`gb@ zvG|2(Y91V)yHWJ;@VKJPxIE)NeXxIgZc6uyaBfT!2V~ifd32h5SpvL9 zSI~^n)hxV+V|b=P)Vz=&n(T#B0}CXli^oF#P7Hz;=1L&bEOcBbUZbvC%(Q?|QYf^5 zTp&RYg~uT)COWqTM7%7>+d{s&84yLe)CeDR;pCAT52SYVlFYVydH0D%dgW7GnkQLk zqmKLK;x0hv{uNCnwPZ%rzY5QK}R z`ix}g!w;yPvM7FB#F$&$2C__LsN)7QFH3`2(<u zDEU#7r?6{z)JKGasbL^Ci_b`$67mq8`r+P^15|aOht_%5IM67?%vgj>fP6&#Sb3;A z-CXp6H;@(Fs)8d~0hDGP@|luuD;rx%A-UQIrP-_i$to}ADj(D|3TzWZEcdFrQ3I3) zXT~XRz+=i>+>erSnzYGK5mZH!U+DCW3hj6jaamI|xsf13ohCg=(P%QJG#W9+^NEcZ zomQQY=oxYd_R2E$jTrL`AKiut46%b1Nuz3+msJ+H|F4N%7+Q&Y%rS{jAM3B%jW&)QXuuP zIdPoESs@x`+Rg#Lm7u@z{m_Z}hlO!WUCp7HhDsClOdw+VQZAC?FNpPtdcWqcV0FsV zy}VZO$((*f3G>xroRK7?dTv)#AU}U9f>fBH7iqvXMj=?!Tm7P%M(9r3F*AmAQ~J9D z`4hqteOehdmd(r94aU{h^aSI`($wq;M$xwP1nqo{-?(;vay(fmC&riOOnD`z1c)$F z!k`&5-+ID`#S%4^j96xB#4;nwPw7hTu$g6-EnPV|W?2=QRVXn*K)nQ-94=(zb5_5UA92iVy{Q{ z(=*2j%lm8s3MjF>&$Qvjihcxcb^P<*@sI~*O4ju)V%nI^m_sVBo_9e2Cd*fG7BZ3I z9#`#c^2HGG1Kx-lMEkap42B1-GebW0H^;D02+Sz_V16gt(`U;L1Vjm@9W>z4+2IkT zcG>7{x%Y+;(t$5*yZ9ss_^814%K-{pQ=+GGt{4Qr^ZLydN|oPk~Glo6AeWB9}C39;JVrVZX4@6W|`xbShf@dP7hHrf`8`x zsN%WzszayMts*!-p{p0EyA|#b*h9cC2fHhQwaDSz6f@d{iI@hu1BwcToP4F7iKaYlN=ey9Sn-YEhoZvu#s=*;Ntz&W8AJT} zL$f@g1N_on4pHT0hfx3wT1P1sr;X~1@m20GQRqP%TSYdb$5@sh1v_V={N zDk^`&OXj)cEsUD-te3pPeLN+#5yg<79qnoJ{bXm~NV)0Gnt<`gytbRiFN2|i=qO6X z7aZxb{$sJYMn>1G02qeQ0ZkL`XCP!wn)1&KL6>m9Xrm0KpeSK2B&2$)tMb}%+uRcD zjs^MZj>`xtk*T8DXj8YMfD6U>d=2G}UF%7yLLP)IOrG-m|QSx$h1pl6s(vg)N2+0R%DaRjE=Fr6RtK5 zFt5AriJnqEudGamzr^GtW>W^sGuV`dt}N~$J!5uM^aLF4VQ+>YBo1YsdlFcK{^A-|;{)F+ASDKq z6pX>pZrgOs1q~(;3qm%}{Wk(ag{LI|Xz+bd8GGuu1qDi+iZ1P-ol7LtM0v}`oq|^9 zkHj!;XnEPV(erWKeASuBV3A^=US=?>@=hfX)`=iA>_L^GvcVX_%HT1NPk)+S!sqL; z#v`r*nk*1-afxU7Q(99qkv5HRaLx|(!bwwhznl3MYA;+l;4*8ZkX$SgKBAyb}n>!GTl z29dK`wSm-qi~hV-D>im-lKId`vi?9@vR(sQ`znoK-A(qo=*D2FFr#J?&J?>GN;3kB zKSf^(g2C5&Qql-}e$*llp7JgM6!-aTVTUFlED?C`tfmsz} zp5TTj@t7(uaSWGLqE(DT>3D&$K80k)7n$=X#_J17@Um84NOEl%7m`fcx{e5^Yz4{m ziYrLu>D5<|OvN^OunbVjmyT!wNK!Fjy@;%AUkf6&YD-68vb1!>&HCOH*j<3KYl z9eLPh3gJ*`GB7uC>BxIUR!pYK%ri`-h?HT}6gz|?AjgPQSz9`CO~|@IV%|_&I^y$x znw>M15|)nmJYZNl;uIOcv%=C5A94aClf`F6X-v6|S~}92o;Kvii7trw{Gw3Td3Xsw zb}$N6#itP6H+VIt*)<24V2$~f2bemw0FzmR2n=vr(;i7}w3mdY6oRUB1T~Q1Ed&CI z`Oisdde&rRO`1OB!t_lhOV6w22+(6YLV;QK?6dk?7n2Nzb zof&GNo?b3e-{2zkeiNxDR~D)FNu+)w%Zm}JH*PXpaeWNbA-2u)1}XuD`by`?QA?cH z(?A`vw%NkK18bXy7^p+mHeZN=dhlWm)RAkOuWkdiGD8Oq)X~$VYc^1s42TA5t0q(} zL+Rp$YP2}8R9D&3;U;95oPDO}w#P{~-7~d!^MI_q-r`8woItLtDv{aU8wdu>g_o>u z3R4^&OQS2_DHJ@TO~}sdS-*K=)av&(AYLT-$BBPwwRcoo26~wj!2&k@d$jw z9qoG+0Mj%wm1db6A~|wn`4AJQGo-}bGN+uF`PONU_h#gMw4Zt;Sd1yN4mGvO`m#aa z>ZZQnuZP_Q3ZfaCG|Y_)WUSJwJ5+O11wXXuhS0a;^sNYeBav!H`?c!Ztoo*u4f>{h z#n`vag1i=$&bN+_F(XU&W>WW-=pH*8Gy&5TQ-{Sz_A7cajn^E(HTCM5j)O~G+?;o@ zP!~66UEJB53SC?p?Bd>)y2$Ew`b-yXGmfq7G_eiK`wqf8Men-#)~#2~HXKaMcSNFq zA2M%b+i+~GZNu@x6g{zsklfhY_!B+%EQoTQ1yN?RZ8)Gi&FdNBHObRe9)PytnDt~f zSu#~q?D#PlOL-BGQ!M4S5D_6v@FKfRv6Nk+7`EY1s-6dqdbj2c-|AlUW!r{h)~WDX z_^MyUQs!bT1tAoZ8VESXSPHgZ+=k;CI?qsQF%oHQQJsM-1i7V;(~u)ZQUd+1JeC4m zZUuuV_7r^SE%a_qHz>O6(+x55UbwyZD#ZecP?IL&V}J#_(_jn zI%m>+x7H+}@cENPdzSBKG%rTpDd(ei)d*4)*EcoNY(I~-NL5#}HZ~cE*%UV}nCHs(%;h8a<&&f=aK zFXYPi%$Rd&AuYA4S0ITbdjPNC=I9mZ9HSD-??f;*#EpnE2fb`N?5 z2im~~-!4s-!YHyCq-d{Qn3H3o%jt!=+qsmeq|{OfxujIvOh~m+8Usd@ZlhFcnNnqv z>ylFK*rdAK7cA>smsq>e|7bqgzol$1pyBpXuZP6+)J`l&?JbA=i{YW(ZN2&8KkBJ> z-z;>tbt8SlM&bEgMNc+EGy$yZz+eOG4k`o6N`cgrZD|nADk}x3tO=v9wNgOerIZYW zR`9?C5)d>)>Aa_m(TCnG^9@*AEKCZosvgjMmzH<>x}Dw*RcQQ$#r0U%cn3pvGp$d~ z7M<>6s>FTBI$EP=`-^Rm`nMYlgQ;|b$uOO6FebX`2K_Q)d2H&GnOMqFCk;;f#`Sh7 z)N%u9o&1dT?%31#t9I}DSCa!{cq+aq5M%kaPW-~V-yz6?vECdj4&S4R)3W&*%a++D zC~LH;5oTXE;8+0VMu3q@4a%GOsg)X(Hw(&nU4!ywK{+oqC~wZ849@>(?C!>Am}%;b z-Pt@d_VT9ID3U_0_YCBl?NY&<`Nkg`oaY;VHpX0c0JA0V`}AE?V6geQ2ne!F_} zBK78W?@dwOY^_iBZc>Za3IaE&(xmP1ECTs1y}ol#&-pw!&IGwg6(&R?fSj8OKPWhLS}APvxbnc zEqzNCPBiYj~WA6Qn6vymOdH}X+M&(Eev>KaCcmNzIG28_k4*gYU{U#SnIc@cgvIB zZv(}UehY3x`b}GxqTfm`1L@vxCe~Nz_o07h@LqGjfi&Y7+HV&g5`Jk}4GU_5z*-Z$ zMI%yj7ejRijq1jn>ZS=J`SxG(*rBQz2^rW$TPJDyIF0H$|W!0DQaGU+<^;3e2Or_onRXWEXyPNC1Fg>R64vMM# z^@f&s2UEzGw}iCpp$lBvZbo@UowK#PmX6=*&UN@e+if$iT$E!E5e<>OHdnM2(=#<| zi!qAwtuhq)h%JDPs*PDXh}E9rakJ(95)~p$NRkNYnRGtih0&2DLkGCL_;hklj zn!4Iz1%)cGzDODO^CN1vNXrh@I#hdUtTvcmA#n3=6G1@&TALss>1QsLJEI@|ZPHkt z+c>aAfNMmAB0d*{2;nOsqV6sr=uVF>+zL0rPQP{CSn>Ae+nW5FdiyO_RvzqpbHDA+ zq1L6wLa$N0_np+{PBH9ex;xEXE8QvM3^L!_@95{X#Rv3-${4O+_1X%e?Q6Ua(rTBa z>q)`4&D_K&YX#ZRE=fJ{CySmci}Yyg-P2^5EjD#so@*`i8}`DRLJJshgzOu0W86Q} z5kF}W_Mxn!$QU3R$)L%bKunjzj-{E&vI z%abk4PWvW(DxdamvIC7?+(^k&UQ(#;>DF9Jzo%Mr8oSb^xx1e=Q2e~H_@Mx5`<9*- zhfNCekgsUK=yT+@18X-cq8Phxif4}yy8Z~$R9;Il9A-OVF5)2gHVpu@9IeH z8$ntB5K7o%ZEQFH-V(NfckA4{mdG^!)BT2X^@DPr7T>LL%s}->*HAV2c-HngG_=SE zqeT>_5&SC~!G>%EPQtO5^xihs%uvU+N0+3(?7Rq>MnE&@5uKe-XN4a6rZ91&ITfMY z6(5eY22?~(H^-%-yr?3`=$b$pb`R-nkEEmLkk0kJ8{;Ug3iN$r?**|)h&lox92X%R z^fz9Ry`dtb#~7^kT1LJxvh77i?O`EnXbUpECWX8WZ^xm5gU#YgvWN1&yznSy&*D3v z2ZNh-87`k#Ot*-P^3iyE6V(^#7`|t~pK--j!Dn2rU#DTcNnCmZRbAqxs!t#upc~P} z5|_5-wOu~WrOny2%VS)cY1%Fy;}U~jb+rMl?S^6kPWhTDMeO+wD$M+OiTIOslD3s2 zl*x1CWCuS))!9HJyHzhWZHuFhA4RgNei{E!U}d`n={LN6NLNHyD%6!{xT|n`n!5@~ zC%LQebAr2s8h!O3Up=lCArk%`;(3%KNA3DJQt~%VN($H_rLfYD{nbN3IMdOfZ8g$4 zR|2|Txi!X5wuXY8v4BtSXgy&=x3CVPc&TZM3sDU8{Qb^@eHlr?oHkj^>W~%$nHRA* zp#>x4MMw?VVtEnEL0cjix6_GRo8-{OXV~{$naSYQ1dtGzh63~{yjitOa3o=>S_vdJ zoFq?anuKwecY?9YHS|tdmv^+~PlLRZa&>t})d6{DbBIaa@n)D(!P{_Dofr$t74&ImSRz7^Z01y2h0OfQ>KqHzculGk&+I z8CsM0JH@q;1nB+Pcf-}?i~RNCL$2@zB+0yXdAeC~wF*t^h?<6J9hKL$jwH-btpmbB zN9$N{?C>;TK^UW#467PV7{xG+1Dp-^!KrBF2r$F6DUYOyw}D5}YVTEjpyWwz9VbON8hWv_aESI zT*q~JYB0KSQ6hVzDn6y{nbKq{IUV@G_D6?O#K~5hUL}D+le4TTsOndA&DH(BpG>o& zSo6{5TY@Ad_?r;%z`l}87-PJ)7kB%zRQ0JtWzy%=q0I2 zu|Ji7M zqRAQmqDvNlk-j+9o4s$QwNHB!Hs@O18#Q}{Zz=KFDGw!?>V;5lN7i1ji8|b|dMnb% zy=(m_;e}TBhRgM(-t63T_j<9t36UT($2Z_+=_d9EE(!H%sywZz zW;t7))o<|`p&kO%J_5j^&rFU$;;P>Yfm=4O1UBuVrU#9mX*?|_mh%!8?CQ(~Hd-{9 zk`}q>d1!n)&yQdWsFkq)NvAw!1>36vD7jvPI4T7cr+0+!?n3z+Hjrcq0?&DyhmDswne~gRpSyn_^-zt(r>5p$%3FLf+#p zL*w3;U>)HIK=-s5ojibhd*eN%bn!2~14uAGt4EAYe867@6%N92vKKet1z|V{WCyGc z_;3N8;HWysEHK-GK>rv`oFFXc=1Y<40_olu{acHr2t0vbkb3ud;HI)(RXs0~aE@2?E% z7)M6CxQs}O#I`c@vZzGB0V@(vmO#h*eWR-{aJAj(07oWr8n_AiZL6*(RRNEns?goa z94wtKPnxvsl&AdH#5m%86OPDYLp`2c*k|E*Kem-+){QP(r{(X4ceZW;MvLw7{=|A2146Nc89ZsU~33Ewc38(Dk@K{7e{46_ye!i zF8-B@9Mq@S9}SFFh8G`8YAqu)5l&lUp{p8ht33Ce zON))NMG;;6aG>m`Z6K~+`qP>z>6A}d8S2G?i2W%qJ!PeES08JdfWDQQ+U{?>3&thU z&RneClzzz6)(>_r^qwpf?~Pk1M@?qOy>L2VPTFXpZ9hUHAF38h#C*L7?QIRtK}ld4h=DQg%h?Q0Vqe3 z3HnW3o;cr%%~%leCg!)|L}roy8EPbQ6C9!w(PNzN>}Z}=23Glq?{{KG*1JSAdl2UK zI$8uD(XZ#ZJgw@LPJ7gXf<|i=*@O83KtyvGu}eMjNKGye&dX9;0@4I;7ew33iMd>Y z@ID&bCigZpyFMiax>g@F?IOBBSFVvpNa^BS(rdSizlXIBfmn?`#5>=k2 zg=lx$cQWRpe&Q}L1=%{)8|))9y&{$xq5?CO+A7#98(PIzVj<%Cy(qGPBz<6kb%M4#*@&di$1VFm?)4!P5xro4INL9p ze5CBsv)7xPO{77~P{DG#z<&7GE{L5jWX4@~x;SV;H_+h~Mi)RcX;BG{K`k1z;1De; z6)4U#9hos#GMUNiNE)t25zCLz)K7a#nqsmanQ8vU%`sR@_xJg zQuBdc+b6{7d+`SrXSFYe(X@**DsvV77T##zV>%yx>)Q;N=p7CVX7%fn47zuS2x=*$ z%nRzJ7!55rs8M~}pc8eCioSqRg2{;8NgHPIMIP&Js5aJLvR6MLnH?P{QyPwBu$QT1 z@5T2$F!Wi3c$xud4k3`jn z!;tcg#yjOnlSg19Ds4jt`?Y75im2b=dbkGHywys(UI?IAzvhE83jlHJcLp(;wvxe7 za@0*qcm(@ej3&Np!6LbNZ**$jc>Sp!nj z?SMOJz47w2Nw;l|?;zbWL?+`TLu7{Bgvex;7$V2rmx+F21d2Z5>IzLGc0gm$cVh}8 zMJsme5Pu2$qsmp&^t<`C?M$-+hnR9;q2HMM5h}v?RahdXeT0hhg6a@2DW-i;P0>ov zHn3nXEF9a@9PRK(>ZR>bEAJ6ES&v#55R;*^2B|o{ z>Pp@G>But-0rEG8-K>f|tz)pD(=uHnwt08s@ydEpv>+Vx(wi>6PquJqq4MX<*we@| zsb`FbF|F;(OuOl0`qD01FMceyP@39U)B=>D7dC-b`3GUPi?(dc(r|8GI$wC8NPJ-; z8f9U8Va0W?$zBh(kQ_n}iAJ`fvo!AukhCH6{zpk~79G+Y3j(OW}?zj92d;odH1fG_1_G11{%lsDx z((B{F;&QK)u_M>_EXSxSU#AuIT}wT1`9zu}{BG9~*sUSw?69--jRcxcw6A;ixUWyTP4VP*?^iuX*PQ z=JZm!OsjmH+b3dvjInQ(E~618btz@(UsO27kZa$^iva_BtH%gAKyQ#t0ts2+*)AqQ zJmbaWil@7nwDDtvTIC0+YxWbZ7>h$!{<&kdTYdIki_sB#vrI8^_n~{nPY3L!qq;i7 zTXD@8(Bp1f>K7B7y)EhP1a~ppMNkC$?c-{~2?;63H8AJzaVBhk+Zo)L*9g;jCZMnD z>D)k#HQk|%T>u6->JWypB%ZOM_O1=2sJ5V_ESP814Hfn*;@8?LUCcNoWXs2rM}Z=+ zl1H-=BqanyHHn#wUZ9f?LMLZ6L^y{`A!D6`5(GX>@YS-E4 zATvf8|L}5^e!`Gn>Rx9vn{#tm-0BJ+8@f{X^oiHqAF*$;BL&vX%$UD&uI0M(nU)-6 ztBkU>r4oYfxz?Pfh%qLxKo`&_TESw*D8zNHLb71>(RVE^60mkJ$5AuWx{$Bjz3d|} zI$Ga%mW*^|AXTOU9hxWYG&onfc|*S=BM+}5!NL2Xq^Aq%(SI5kw~KJ63xMVnJV2um z3Dr^_hzt6aGDSw#;0vpN3O^-wgbPlpq_{`+$u zY2S==0EhM3>R)?Td#|1v>O9WW>QPAi&PqczjM2EDX21%4hZv$iPz`|B$dSC&tnOZe zY2B#0WPO&8n4=Ob5|?^PR-nVrAU4EeT+%HAwc=FC&2UnLypTnS3SIMv5F_z5%kO)S zgvOJ!BrXb`hQGax`ow0-O&q-{fMm9fCmt_VsW#rAPh>s4pD!*;(;CTqXa7aB-NrL1 z;_8B<6S;44ltVk3(THyCUCaNnjE^$CrQe?zCuD>tV67Z+!(Ko=I^OTdxYXc|*%5!r z%9(FHHg2m-+OnhDvooz(=EJ5oOiqlCb=oqmRf9Jd-}ZpD`#7)ScgP!|6%a88nSmyu z)SS&R3o}9|o}w#>Y0=UL*-&2-5iR$(%;ivjcbmI0Dd70k>xR+V`U$glkEgu z?`3~Oxl<6@Q2r;}92C5|!wkpSV2GWAw6Z>Iw?1rEAFi9z#y+9_ zDRZOrc5jMryk=%gxrLUP0XJ_fYr(y+O%4|G!TeQ0h3eIZ84GtGjXnftYvLZ-*_wEP zcD80mji7kP7#V!Uu=EGv#Ggvxd*lHEftl>6&SsZM_Ll6CqjEU)9ipifL7f|`2#WLW zjTETI`B=KNPH?cNTv2E-_$jf)1HuA~*Nm>GAjR^1cRY2o$tXb}g5Lv_8_e_a-jNA& znT_DgTR5B*U=t$|vjR7WsshQq0~6Tc? z@rki@owMi!HvO8ID>iD(b<_|X=tB@YTBDAi@PS_r{^Cfc(fq}R zZlm}MzI3V6E&_i=ITq#4Xbv;eX9S0diw{>s5xML`B5dGv*x{rNx72~BE6H{ylWb3M zlra*sY$1+Wso8-Vdq`JFk)#YI-;!GNxe2L7tuoOmortL%N6u=8YFPTfiadPKUQayy ze&^u>l)}RY2YC2EXjnsh&t>G{#R}5;^rCmec=#P_=3$+Yo(Y1pSeppCz{8(61EbQ8 zmz9Un8>{p1TD7AwFfAGbpJU85^?1%lZI<}1#$WrWF9!pQM@K41Y0nV~(ySU6qU+AU zoK_eqA~NtF!h|BRGY+Rq%)qY0a~wGXpVrsWCLPPy^s>)7t`s_#nz2OAN)@vs2Z&B= z%wB*pw@y$B8=ve%Ra~ZQ_R1sBa8HB}vKkjiFw-?RVF9UKjo%bN2F+jWi)j8T$c?o& zw^8qece|BITzzKL)oMob6n$=c!gppk$I?vG9HuW}I zp2A2SFTZVJc4DHnng2SQ>2mxZZ$eL6jW+)^H3vA4E%({u@B8Ny>>dN$H~7Thsc*-N zEH@M%P|CBVT}i_*@ORjQc6dNMj5p9Z?Ky3*>Z^5vyPU@!X4|dK1pXGY`~ZuJ7KrGQ zR22yzHT*B!2-V5&GBjke2azR83`eAt;Rvc*gEIpaBSw zk;^PoD?VGH5di3Jl@kCvy5gk{VrfdKu>~gHZp2||SCrGA;)rSjrwQ2Vsrq0cmgGP| zzjJLdzdIam)YRlDuEUgj_8ZgACAJGywQ+eu52XGU2ci&sW4PT+sC5R1MMUsgIaGRdFMQVXN&GkFd1OuE-!f^`+v0bh;(;wQ z_6Gz8w)%r7cwnoN{Q)yiojB{F7I0LzRqbIYZn8Vg#yln(XU27;snL#+9np`w3nQq> zyBpkb3&-Hm$`vO|!B)sJZVKqN7PHjK7-BlsCAh*_r}b8?(+|tXr_*N5ESZu^L7yd; z%1xLA8UKmPXUnkYb+j#WQzjduG&w&RCO#Ww4&5jvCGsW93i1_+8Gmil@8USSzc>d> z7=76z;?VYp$tGitNeM76QAfmwLU1te$uw~i zLC8%$x<%38E;F_<1RQmktv5vhX;0szfFy4*VqVj0vj@6@Mw?V2QyxS=%E^b2a)k6A zOp9OY?wV}?kfo9dN}6GHt$C!PVN<9K@rVztX6=1+MQiV{HIl5oN8H*wL@D?@oLhTE zG9dWSq41$#;R%w4v|Wu4472i}j%ej+nKAlrj@`)3%G)9V>P@e!t%vmm3UWJ7_E=?E zu@IKKBmoY(1h`g&^1ij%c(Mi%Z|549B=4x(cY34hfx99pQo07)PFADac5hpl zoy4^3VBAd%7*HXvE{a1v^U%qxe(h922qeY ziu=xkW&GIMM3 zOt9R+hy!1b?)uFVU>d3@!TPpNE*iu#RWlJd+$80I~hlr6O zNzVf=0fQ~|p37%Ty08F7ga?8?O1`zh)!-xFhW4>7dR_Cey8_EZwevx+$C52JRhry_ z8xeA5Q%zP5xfxxuv&x8M0@tJqQ9Ky)CgOn8-f+S5KOu$ex zfw&>&N(Dze%o@ZN%^5vp*v;~c4%JBG1D8)EGMO=2B;uNn@+EB^$%8kwD92hd`7H3W z-1h^dzV< zf460h?6Z?AxKgz0!WcM4le7*idDg<(>3~7U=VyJ?m&2wJkB-bUf=fp+u!Siv5d)v7 zC?YcOZ;Gmc(+P*uC1zlSx3tKu!ja?UxV}D+XY?zMs}XrdOV&tY<0qVrZ7CmX-ZD1M z=bes)&n%C9e0&&lSB57Cj`_UPHsEI2MQV1X8K)3}7@2~vJPXENn_+@vDkXZf!j6H}2j5zvV`e2VrumWSW4EF#Y-I9zY%u(vbgaQ{$E3QXyZss~Pl=QG2kbr0DL z)0F+!VV0B$KF0&;LpHd>1R6Yy4@W?EAQ59v(P zT?=EnsZcXBs`;gDoLc4!26R*#YwcH^UrISyDO|fk){5Ek>)ZigZU*AY`7)M=A0~1_ zl8ka;R-VYoGG&%cJb4p(JaqC#JvMv!NG{4HnvS@539i&f zFQ2--n7n+OaIvhE+JsBWPO+?%ET?5HGc40A4tMew<@a_kp#aPku<~gu|z6vmO_bXTl!-wmdd!d%6*<&x3(X zv`j^0^S-F-^953HzmZo`@(;U`U!)X9J;1t3&%i*vOyp{QF|@9h-_c^`JWXnl?K1~9 z%X7YZjwv&(T+-?}O}}L;=u&g$ON?GgH-WH4vSw;rCB06y?1ts6p_}T?IaZ!CS%C}6 zR2~UKdf7jbEcpo#B?EN|B|f2Z5J*z0H*&@sA@4=a{Gm@t1xtQHsaVzLB_TW2db+bA z1NdoMR>?F`SYP+lxaA-N)zh~6cZx4d-|_|Nb2fZ?4N0Zr<-2{`A?P& zuJzRTU1S{E#Hy`Q>(ukfP*_34ZsIIT=U6+9lVjBa$7&55i}`JrXCoaTn)1rdjVoEv zlEzp}3a%E@;yhcFe9k{_XoTu`wWcr6rO$8a*)A+h$!b>*W+m&Ne=2<55t?%U;v6u-tJ$i^e3|VL8yl!)g#c5dtb2ssRjlRSS4v^}?$1yoWEGop7jKFdrzlRJjS(-k*H z@%vd=S-f~!qf>IAPdwX3HcP9^DBbWvnY+VsX``=SplD<@h8?SjgQtFIqHoBY5Wt< zOXD@jB8vl@h6M)1;eVmhxP6(V@iF7zEWCXz@TSY=k6%7%oJYr!tc}umS#&Jbu*K$e zX?&#O#wd+H8l>?NjqVDS#^yyH&hg{8B9ISp za7Df!!NJh5#PIvH2tSEo_)r$`B?@J;(@q|RKH%N3Q1*N1h74fO)=38Nkhv(fhRhpz zi;3;vOZ>BEF_6t(lp{U&3kzh^qM2fgIcW%Ii#5V{#|o@^Bw3&h-+%7nc9bBLFglQp zuQMu;ZBZ0B7sS;~-n7%kg|B!&ThT*g`Ul*Te3OyJB@ScToZ%Vz5T+U`Q|gWOdE0(L zNc$&7n}ddw@79$JsW+G%r9GTs+xs&!svEsf7Y+BBG-JGRvBW>hjj6!J+D}kkuI$O+ z(1>G1J7)-z1BpqrplbRyBF%(5*!d{-L;+IyTP@cFxPg*?ea<^UE2vG})pmK?$@R`=txUyOY&>YvAo=V zElZ#BKv=$IrF@~fUz>8?l3y#ANnH+Yw8CJbNAHe52V>azrVeU$)k1~1o2Bq2u3-qy zHfwfPm^0J{!)$D03;b4efX~=0Ksq@i`M+o6=vMx3lzZ-yssn7esO5*rZ|1}2c*hqh zGX22o$17pt%>G&zB!2TX#s-(eOTHMpY`#TU$+FN1E7?JK3M)wvy)1Efl-6J2{_@LA zq(yhxg4X!HE4$0ABX|t!3Em=hWMRyy{QO45pW|r-H(D5rZgi_W8SDFtps8;=oe070 zGh_WRPE#C12jXCd9Z+!6ePghEj}(v1UYZ?N1jM5g3%(EC^wayB?a8-y-qwy=uAOeB z;}4OqeqNAHZ}szn6mhd7D=_hNqALRgJ!G@nm5xRCHMUbC?a6q`V5NI5)s-Iv)7|&| zo4&zzo$T&g>c*?Tor+gyzV)sBnSIUskiXr1AD?>N%$>dInaw4OAi}vVgch$2o&!Uf zStuJj8o%-%mKGa#H59p=w1Ow90vf8L){)32L(G5yhm8wy;zFSoT@EFqUt_5qyEr6N3U;0GCXKR*P6zL6g! z)P22)nJ!g{q4283skr-~@0)v)InZ=&(Wg!^pl~>(W`_M-kw^D0E~?j|uUsMP5NAi( z^-<+^LJ`#~;S=Irf5!(k!%|QrOn2YAXCt_O{-0*xeq_dnr^6T24DE%%Y5Khy+~deH zjqaF!8Qx?1)e7%cZ_>^$I==zR6k2(J_hsV~+>>w(<0DQdq-~fa(9qp?VD{^YUU&DM z*!cA*+wQ){ir3BT1Z$dPUcF~e{QGqU{hjL3PhI;BGq*TjargV1fj+;7HhKTPu*t!$ z{+(fa?)E-g%MOWgGaYXBb+oBHBm(tnKezS?-AsmqoDz+cr$0^i%dzrr^jrL@t)R1E z2b_K`Jb(CO)$@kVytYFKQhfDR?D%v;IM&V{N(B&xZDndyCmK|+Fg_JU+OdC7q=jN% z;zW0P^VbKye_{()0N}`0XYVaE0Ah;$wiR+mhkCG&2frscOB9=|&A*PU*>Z7_17yCr z-_XU^l0dTbK8<#+JoCF6%_qbk?9WSV_UmT0u|HtDY(2E#`-19RW!UaZUur)fd!hX` zb8sqJN!xZ-2g#hQwZmHN7kbxLVb{Z-;q&XquDhpueEOC(efs43ej0LJ3zIy&zD)9B z8*uO0`1CG$wBo5ncH)%~<>(JlEmyq-c+al3FGRMpTa-x0A540c?oJ!P3)Z8lJH##8 zC7`@H*Lgbh$;^>j zP;j4)!<)xp-cWo&e9lL>Jw3Rw1f;l(O(ppE~ z+A*ACmM`0Z;aZ}drZ#DRza1}&E}U;IHnkrx8-q*g_|Y=TD~}zOE5IowttSD46sTmm z6sR2vjTv&hNvDCEi^V_JXe0&$3HZqQnr%7kUt4~JyCJankKnn{ec{@;I=4D5S}6w- z3O%@Cy1X$b=h-k8;KSL(jrqpYBF{Yy0nEwysYtKUraM&?K+aFbJ0oW~l1n4Wd52hP z3K@2L zN!e@o3}#X^lK6tGdN-L?vXZp%Hax^nhj3YxP4Q5qbVNF<*z++7FkX4zA2fzWVrE$NPj2f`6$1U;h!xR8%l2f`m~A}E-c#F@2D_>1DO^&w z;^5a|Mxvo2T7C*Yd%ygcG*g!5lwirGN_Bg&J1?*(!0Q^veAsYYpZQqIXbZZCpisXn zo#oz_2}o%v%YW$4*b|A?$67j->pr?HGuD+kT?;~=4$Zjurzh2ci55{p%(^!x#g)Ls z32}x{8Ch)SFHP~lkuojbw7;APZr}?Fm<)3ZkYvwUbI8SB-ye< z!))ZKgMr-ehV4{q$c^4@t@X|}{WjDN^F>XeBvClP=w~uUXGg!p=oy3i$er;6ldQz- ztNEy=8#RX8b#-4Kg?2j@JmU@O^Y+L-;4gTkLJ}aV9Mgv-gh1p0{i0Wmk@rdcLD_~xtlG&CoX;G%n=AKMa2-1u(}zHj%P(|XtSbGVnd;r%OW!%EjbE7X4F7rGUK%(=qpBK1Tu>v!#X!8 zF@T#C>g9}11-=f}2Z_Dj1+&df)~{W|qadUtgWIu;JCUF=Q!15S=MwR(f@yvzp7-K8 zpkU4TSJdn>D=8C!m6|e{;c5z=$!!gTbnypLGdi-MQyzf=(VI1|@jtWo?$MH8SAAza z?yK+Z+qe30`*pk3zbdt)+mc#pJzKI2>bk_QkXbP-7L&=!tZ~+wKfKymS(fk^W~ObG z-7V2z6AEI308dgj1~*`N3JgJDla!4y8X`iO01>fC3M`ELF53djMp*Ot?tRYr{i<%= zN6T#!vSKgw{nh@R$3A=S^F90QbAIRi@29Jmq&sT_3DTs|Kz5aj)qtdZ zR&@ssyQ;ac74!GIqOC?<)5(>8h^1F9%EkRSl7!pLooP+FyrNEpXvZUe7Fy4q?D(R^ z3)-nBIYy|voRKT#1YE2giCv|@r6C0j#uTdz-6;iIA1sFXF>XVBOseHlsY}RES0Zu! zTI{A2R6B1n3m&NCznZ&~^w2yO2@7+{(Zo@(%Xkf=@%8K)9R2Wao^KYFrLI=qA12hb z-084so3=8KPxaqzQ~m3d?UH4?u4vLbufvL2a5CefvafrtPjw6=@NLyin(NcQ!%UmQ z6>uMRA-|{oHYQ2GHvc~+N!kXTtPuPB`X@=p1&jY}Pm-{>I7uS7ljFPg@cr#ik`{CB z7Du?V6|ui_lca0a9GfIvJ2FYSRqT-(Mmg-*-vsA%x|MQ5CQ zKs|u-kBHv{SE2Uh;3AOjG6FdozrG=nZ9B`~q>j=waQ!kX%eLB!plr1lxfWJ?Ly#H` z)GSCH=R!;|(j8rCc4z_c=G$ng`&1q(v7pRU^DT+&aT1HrSWqpb_E?F9Yhw7sK9bIE$AP;*s%~fyfP^58{)Zp1Zbkj;_X8Tz@_*ZYfGynnJa5OyNXy=gzkNTz1|#QgZiKrzb+YH@2lW37 z^S7`n@=Xqw9v2vxA8>rc4={fb`~a-tv{k>hw@&i)MNxcm^>U72_*>Dopfaw-M6`5$ zZxVI*A3>)pJz?RhioZMRH^*1~WAm_QUz>xj+%6wZpjO!C8QXI78@_eP_I&(oc-De> zeAfQQ@Qh%^>wgE4Nv>G1wuIOpyL`QAo2#K)fLohPNE{n3GHSz0KTXT=Ef)pvaelE2os5`;75V6tw-1>yXf z=gWz>T&L^3MtAK-=NsqxitpOpypQ=}B#1yr(1r z+kghPov~DEae;-MnZCv0H3xS|eO?<~ z*%12)m0bIcAW4f&*re_0@cvUH@74JZvK6;ks{Myt__$Me;0we)8e9c>*24vgKUnNT zdBTVLrA!=)kgj2OZWN4AXfUlT5JvEX9@2(hrTA>RdGMcUb2&48HYP&Q#vxLA)FT8J ztCSvSUX6t>#18=r3yP~6j}~ZsVpIj3+7MLm#Ss;JZn6sCB{Zl}E2uzQ*pdng``2vr z4_UqvMEq;xBIdm&$zKcae{mYB{5bx_ z6-47C!RgR?6X}?ijD`ejL7ZjsxKcwu;zY$_7&omSXrD{I=3pCK#B9=m@5?tf-5#h3 zMfgVjbV5aK!SoR^%M3pLP+y79#TPXG`Sib0#piwR8EpnneeY@gVhdie@0CaT-a=G7 zE8g4bdzYlpv>APU-+RQ~&ouv^pDp&yjr(3%ySLW&J*{$?ZKmEAv436fYwTXv{~CKj z?kn5_F;%me(LU&P@vkiAy`lZqF%pW~yTH?LgcRO2d^^8c=boZvjv)N*^ajh!&6N0N zH1zehxVW(`M*OzW?9R0}ez4?UFFf|j@a4!fJNbLfbB&#A)+QQ@S&kpBD! zOJTGBhj}P#HDG~Mt}o!U8V3^x%d`f&$%x{@3q}0o6Ed;+X7PIlFZ`W)Q+veG+ja^I zJA^l^qecUFFD5qCLGY%Se;Y`vcP?TV9Q6KUrKSKQWTL%HTmh19=@=i@WhWwEY*qo zMnhMLJSvj?b?t}NnK^`0=NW3)nDq+&5E$1dPsGzDO-0Wo_uA88pEs&j+#=II$7}D= zbVsdbwEQ{K=2Yz$0!^I+ZN;%C_3y%6nmS$~b zyj!Wqf%8!j`d)y2zj3DCQVMW%UIh&h+#gIK7y-wpBj3=p&j}Ih_ zk7l0SkrnQ;sTEC=*8UU4jj?!ziU=F?#e+t=u&)lc9=iz(5?joGKP2^Bxfw8=P_-6# zr2EZheNSB3s`>VGs`)fdqQuIw4(gd|e#V?e@iMXq@g!v7D4R-^EU;^~sMUvmf?_f8 zZ7)8MAG4_0Bui@|SK#xL1vyFj0fLBt<9T%X|cw)#$5Vk=!QH}F+oGJjVJ8d-$Vo8;S#Ey5_Vc>$U5KBZm*Q$($+0O4;EQ{%8$mGL@GFj&YA7ZzY`CXo9vc-R?ETeuYKIk6eH;|KG4bQLP&%TS z@on0Vm$gmXbOJD1L3V;k=tpVK2a@6$b2ZLT&ryQbH zN|@CVI{{QVN`enkS~RD5srX4DoKyfh8I*BZ!8Y|{-Ig9pcw;f44R7lc>ZnEk<~~@d ze%u~2jzc}gnrU1C%-LqNu61P*W}CHM;n9KvVBEOBPA6g9N%=_5ZOp>Z!M=L)o@ybuWc^9@hBnQ_b+Xq6o!r_AllH zeXbaP+4o&PNmuP`^nI6R6x2o+1aGID9Scnok%SX_Qw&YoDXf)rRs)lQO`@Mhup5uyB0SpR&mi(`q}h zqsvCs4m*+H;;|_{?bbx8+Sb-26+sM7J5KG$r4LOB7VY4(C;U-cnLg%^J9r%U<2;W~ z`lAH+ls|GaXY(`uxX7b!gr;>ZDq`DPwf2r62}V4BTRe=7(3?)C7vyQrPs&Yji0>_QGb?p-U@_fg7H^-NJ)lb-479O>IwZr(^!xTf}R zN-t(Uu}egT#vL%SS8X-|<7l&H6b{ph4SksAgoa2mcBr+E-RGHuuFa$MDoXKODcw9! zN_QXZT2Qoqeg~p}8kZ+-r(-tN|r&fLoo|R^KuWN|tsRuw*ITF)9}=$++4< zf(ts=btc}$1%N1f-&%I@UG=4G-@EDu<=5NY(l1&R9!hGZnm(we0P6w=^><}TqsRaQci4QH7_`$dQJAx#ZZxFui0)h2LEI z6M+0=>AzOF^!NUP=<+%Wo#tf8fWU-jX9I$nMN5->_~OKr#g)tHKsLL4IX{ri^cAdB z=P{VPpI|^o!PX+!PAarsgA$hgE)HqQ2BG5d-A`0wot90yMn@+koP9`h$-Y!RC|o(H znb0zlDOG`+FcT_iCL{o7CbS%8LWh+4u>LvZ-k)L9VPGlFgt8Su^%4EEl4;Are^v+B z2{Mqkro8-9P%KA|xsf^h?^LIOIWwuhE9}d&ur1by73EFN%C2lF|9#|aV<|hB|Hcz3 zXNU6NOnHywzlemFvK9Z$orAqHS(LXZ+X#kG9v^u<>Q6wl2LN0PczDCQpK*Z#y?n_tW6*F}C!$6qSHOZhE*apk=Y zN04WP!M`nzl>Z|`dPzmt>WAKXY)wa;B>wbWn==U-0mtNoBL!-k&^0lb`4KP`90tVC*ijKlg^on#ntu9dU) zO9EJpDFDrdsxRp9*s8`!Qz0}5{b^hC!5`K%MoIQy+bIdoW3&DJFxNayHB1GX@BU%^ zddo%rt$j=kGs%OMLA8Ehtz6%?(}sy>SoatkEW-sMhJd;vWNc2L@NjaI`KpLtX)f?| z*_?!@po+_KV}Cvl%UU#^+0`Mq+@<sI1cD0BKY_RzI4p zFeo1}7DZ^DJG-kob)a&fI2%|pYPnJ(4)FRWNZQT)j#~$8w`Hj-M%S1ChnTD0j@uSD~qKFIn89wq4aMYY&GP`b87TRP8bgwan1G4zDuA}ES?Wmaqg2l zv%mJM(TBrmtoayCnqozhk%*!eb|R7ux!2g$%ehx4b#8ky>d*o+5L)m7Z^1{IdFwFh zU0P<(8=_B*_vgUz{<6F9kCyAlC^n;_h{0g8VQ`lm#~eOFP7;Q z#I^3L*Kz3&tFUT<4@^j)&~Q*_H2=iH0(B7;GB4HZ3Q!zN7;q`CQ)Sy}{`!!WXHNKE zVX3S+>n+2w9-po^lI(tFR5dSF=s;7SjZBi}Wa>|uuLm5im#b&+-+etm<72&?sI{c2ZDJE(>(h+vO58L;MUVq=H@uYkPhDDzkKrOSu;ab0?d zCrbc-b++`P#l}wCtYuWh3(6;Qb~vf|BCQDgOSR#G06>;0Hfm1dWHd3PRw)`$Ub1)< zvb}oeRq8X(uq0b3#4iY708=R=7X%mwe0K+WB@Q%OJDfxPV-<&X?i9tORx76jj7YX4A6!v1UWNYLKwnuPsiIIgryi}Iu7ATk8R zV&f3N=91Vi@SgOjA%OKeJsMom@Lk!pFIuc;$Fpl=rRX*<^H+@3sT3j#WimoGH!kyP znV;UxaC|dQ}R*9;BhG~E=h<~Sqf!G zVO&PpJ6A%(v6(c)FuPyU5To%>pJN4Eq%sUpcM=#rU+w4ZLb^{qr5WK_^nyL=xSGQ` zJpVH{$5+;`qi}$^i!!wv%ADl^X|IcZo+^7qtc=5g=p8y!`(){#f)^|5@~g=F1kika zHHT&M!Wx;uG7M)1%%yDAftf1ns{-a5)}G^kKm3aGYYc0x>_YtpQLjtAh?Un-PQrZ! zQ}rxdqV>NJT*10$A=p>eR&hc}5out5ycpdnVA2b@XwG+-^deST#+(lwrG8zM9;Xrs zDkXz|Ksk*YUr>6dCWOq(J2s$_c&RA9GhQ2Ao_4SB-${$ZpDZ<@RO&a0lHFKu=xr{; z?Rv-vS3}@6J_KH4esMLsQACT3X9A{%{iN3>(cYDqR6}%V`imB?(&OET5{Z`TH_9~B zHrcmV(ui=GL24w=I9qVUWO5lAu7Xyr%p;`a#|aZ}aEmh~&sh;xE{$O2%|b-5@|u8^ zhM9CmRhzK#n))fq5pQ(8Ynrb!c$@+rXLKl8{C{?{y(v}8)oQhZbv2s5tC$4)*6b2s z*3s}NWOj|_;|4j?;RVATFPI%Qnjf(jJL36?D9vP4tvfuc?;DCX;3ENOwyRp1nz3bx zlS+Ymy_nr(av+GlPJ5DBbi8;@P#0%FI|~ZATx`5X(G9+X>~D=#00@)K6x&=KbIn!tr!3w;`N`Xhvf; zUKrRX*|-Ycs|B@{?3P$I!nT2bw63F9&)c$RpM_!t)U$58Q>H3L$_5~&VAkcS>lZnyY!c!9vWpF&fR}YO7 z?r7+!33CqvZHZ9Q*ak!S|U{MuhG)yoJ$fb!EnY=fo zb3zum$x@ZvSR#ikLEk_d5py4G)8EH~kq{Zp zvhc}^y=J7-`^Tn<&}&M2w!wr?MzJDh=lBD!Q~ZHdhB`%PZ_rNG3aQb2=J8iMrYy|) zrSmsvZqMJAO)YotBwpvx8{A+G;;J@woNYqy;Zf+_sUqY(sPudqVaQ;H(!l&;Wy4r-vgf62KDTFi;@6S< zME$6Z(k9p2C3EC@ZIJ!(99GA48~ZZ0ayhViIKMABT1OF9g#`gtO~t_KGRnmq!vsc) z3Ngfi11Kvzc=;1w4gQ7E-tayuc?V`GT=6#;V}DDP;Nva43=D`-tdyMCoqeKQ0? z=aob&$|TO0OIZiqJWxbxTP_VNrG_nqP?4<6!nmxJ(hc*qQZ6@Q72ack1V;)h1Y(w5 z0UkL*3G58;xRK&7N3Se*wmiQA%InjeE7@!{`k)qw4;CA(EdV?D?0H-m$U&cEPmJH0 z#Y-Tb+c;_wdr zBZc8OT$SCCTX42qKa%aL-y!4-k4mCmnAHzb(xKpU*&@q`=T_{An#h>vrX_|^&+TK? zeA!VW?fx8M04dvPVGt9>gGmFeU)aUq7uExswq9|vv>Q>=vueq6+XdgeJnY7UtZkKo z;#2#JZI=eLL4rS*ffbu0MRpWGFw>=W-?<_I9>m`|ggg&x3lC>+y@q%AmG{$trAOAX zhq8ls*$1@WDDH339M zCqUMf8%DrvFr8Jjn*0QRZ4B_itFW4ku57=AzYpulFsS*HXv`qe6;oFH6XQ$D@a;>= zj73{71$&p>Z#pVTN1)TLYN=c?P`V7Wf$?=aa@LJA?&Z)=%SFJIF7v#F9XSix0ol$n zeC^XCvy*5t>W#LGyOQl=<|KD_S8#WIPe}7ue^BunCNbv3zTIaoCP1{BZ@Z90(P-LT z5k#E6#Z5XioyDLhI<%mtjMvux$94p03g;F3jsQvtQw|=waoP{l7|5k@4U*Y4h)nsA zgX=!+pTdc7ys&-WzEwO+XIt>OkCKLOY<3o>B*5#oHy2=UadSZ_D}lW!I%S6MZK=I0 zO$MiIK~vCZJ1TzJr$|9PwxOc252IHnaOLExvt2Tx*8YW-%If9lyc5Qe*$a55?hl`& znes)kF5q)8IDJ1bt7aD`VPtL1oIMVUEgG=2jh;XbwP0PB7jaUTPt8@6id{am(JP_hHQtOU*xnE73C|GL&o%V}@BmXK-x zrEX&hl^{c7bk^<50VJB%TIk%+CEG^P10iI9S}-&3pGCtjqnq=k_MZ@B7v z1&yxH>*=2|0PWN;sfa7zgRqOvf-$$?TJvPF+Qr8y;kM=f``vk_ChgM5-b5z zk&)qg9Mic;24n{dr&VKUq3sg0OD|n$`@h6fby#y$QkHG;ZDC_)L03kB3OR z#b{`IiVgNE%BOpyD~gW=A!4KE+T7xHrWlz%KhiASdWeJEQ+~2qRZXMYILHAhyiNX& z=!WT{7eP*+!SXSS#x=%7?ZA^?!xxjzB7+<`$Nd^g^Y;b62BAVz>QTQ&r(?Z_H;f{$ z<_}qYOq8(L9#S6N==K!(CvJ4Rx%7X?j=tA6PmlG~phOcDX5)(mk305BQX%MLN+ukv zuU3ej&dUcE-k2AR`34YJFdu3UzRIG^VUzy6I?|nQwCc>G3@ac6vYkRJTjl47|W*{IA85k&L_BPB9zkCbrgkCHOw+C2?gsHUBSy% zxgP=?RcJ4O=EDIr4Mf3LS7H$~p->9{@-{%G@}h7LMgWRqsM#JxO>&QHFMfYGr@34Z zpm68ixNI-t0_cLT&ytF1`)4m;Q_PF=O~o5vEm698Eu&SMR|G;Mx?)kUaTn$Ox_vyO z)+1LtD8b~(C?WA`l+Y-J0ea}b!D=i#>V8Y-Z1Yk}U3BIBPdjBisa^(Sm=;;45 zZ7ghZxiz!@(o2DQolvB+Lg0aGDjR%3n3d&ra-JoQDRr`tr}Ta9P+*W%Or`gSPNsXVNMD)tA6_m-=oZtZ0_4vLbSogl!}Hjup>k*sE$t)O>}ow zY7YI3E80`7DzKN@+1j6qb?U^#+15&PUA!_pQXnRxodG}XCtuc!B{yzsp7LZNOtG|3 zdzXVPjjI$IS3Ry#Mio)&*#-2Iv0Ta2e>3uiUBH(0O#jQZnTk~zDV$+Wldn`O%){KZ z5;iq;pK8wkbB-0A|7Wjip1S`9CHs(^gBj-kp_#?5vvrP_soR%VRnGUCf3>Artek=8 zspiK^aH#i`yOaKPe|<*XNg|-^=98s=ZpnAj(LG6hW}(U3S0SkJM(e1S2< z_*@`}VkU`Vhc&ViMX}>-9hWtVf@Cg=IoeS{5dV|p#gp0`Ud`I8r)Fso+fh~R?EQ7y z2c(2g&8CDimazRFN=i9nDQ5~Pd6AM%Thh)C%_!-#C7muLc@tVJ5t;PcJm*v#CioGP9A5=!M3TXd}cl$83a)0oL2dBb92^4jsALP`JrxlXnzd zcu$WqYr$ZGo#@Y;G`%+e#&?-@uMq1()@tb5{6DsC!&tM|%|!>p=v~#`wm1=Fs``W>S$XI)_^j$<v;fA9nGjI9dGCD)Y`S^uzB=8OhyP8`xuZGrnrseZBUgo7!lpUV$WkH8 z{dM);>E^2?r8$!C6zIH z|10C1soIa}yD9#*S|1{MI7{>p@{D<7K4#7oMJTrm&1ExZ$tby%b@G=B^s@3P7dUPE z1iz8BnQ}vAGvDZ@{h5g*)HeN%uI=e!ZPxd`k%IhOu{JxQ;u~4pCyKS%F#V0J?Tf|Q z94fs((JwN&!gLQ@Vu44i_A+KD>Mo!fjxLY)-p5;cE%s~YYgw`47kBaUZsxV=^&&&s zw4eF$jcm(bT3ar^Tb_D;y?HzvZC<*sG1r`b8Ov64&C_QIEY2}P888lU$EIGZU-BR} zlfqoasbwo<3TTr}KQH#OIb{nSa=Tr`>k65eBouYb>CLXyp6M9J!(5qSk|j&B=e68~ zImrx?l|-{y#4R$cknf(&yegaa;c_O6PCYW1!)Hyhm{M?VIu4hl14%Ws*{D{@X5(&O zwm22X!f_x^lOHuT4TvCn7!Z>a``tEykA?9U$5k`ZM)g(AFgvKSi}>SjXtfv`HL&MX zD|y_7Ndi-=&wc6_KW>wRe_WWSDGFeV`ab4N6~`Q#oon`wr_CU(F^BoKajfZjvuvgz z;Z2?8J2QSQ6pP-%BcQmEqH(V$6^)elpKoM*`S*8ar38ZeT4c|mmZwK*L9{+uSJnrW zRq>UKzyqe}7i(%CzE`s_h3pr;TCk2@DLL}NIEVq_W0AG?HSxrZywd;R_rC#xw4w@h zCO}z*E529asd+bNig4$s{icTIE&6>b|9wKg{haNR-q-cpjtJK3NU3>9zdf*Mzjy1m z2Ndo14*j+RojtvbTy_d8>Q^#No8QW9O+Uh0CfT%TL;xSHOjfN+VEkV*t6dAFGJYy< z>fDZb>o$+R!7VIy8=WH7{COkpik7b>&~o!9jaW-W4iYRke{hVbX-4y_X0>@rA!hS0 zjJP*t*9@WgM@HP8h?>zgf5(Wa-)Uj4+qkaBiOpj-Q@601wTHrE>y&?z@+hB8CPsmy>^7u{kz*5$%EH%78R zwI7*N)#4dDvNS<$YFc&ijWmqEm{EKrdA0V(s<^c9=IN10WGU23-#A%%@*%P+h(9%M zH~NiCr_`A&>7S>hPFByMginl-1+|d>VvJ0$7Wt_$GOZT*lVjv*Cx5C)rrXXq`O{YD zwc>fAXv%)Gcp!1Mox~SI;v?Hhd?6%0xShnUka*vA5}$LHYuicteV%sbcG7A;1EOGc zY%94nfS*@mXjL<`_Uj1}Tl~CQJ%c7#2q#WTSK)pC2ho|HUquqdl#ji{qwMNZQ{nSd z?YwFJWw6roW~G%g6z?B)1v@T{+Ohkcoa@+A4eS7Fl!QPTWt z*~7$!LD6v?=m(W%ryP9LthDfh_m*F(1#zJ56~bNM;}w-NxUukj?|n>Z8~87Z+m`U6 z>(expb!1jl3-M{?QY zF4pkEZREr0r-p5GoW{Irn710{V-4HrLyZNi;qPsO7h)N+&86?UivqvrY-7=~ z-?feGyTsrwV~~^JT*$X?Bj1wNJS2rv+elnfB{i$07Av`N8~K=QQNzo(k#divT-`>> zz2arB@v_%=nYXMj-9}cvf}fG7XH3+r9!k{9qAVL_*(v))*>9BnPB|dT0izsn3L9By z*>`QD(nI3+knwxS_@$`_EcZXyM()GPeb{mzw%oK~KS!yGywk`#jm*%n%;q|gcNlqx zk$2Hzc8iL+9}7Ck@5~&c?YdL zs$LXr(P#v<>2iqpsx^=pQ&vS;HOi_}h?QijA+s7XtAScqIlVyS zV@5t^WNN*RR*8I-k*_i`W`8Z>7x}1>j~W?!Chl@XK{S@K8M`tez8I z&n=?dVw78)a;qq}8s%1}+@_3_cf!g$VdYWvHKJW(G|qX$%n}>o!O`d`CGZ|y;w`CysTE>7_<@wC_+?RbDd8(?SYE`iL z<$J&9Z1YEc;7@*l4G%9;5p#_fpXCzOswF=|@|u#@EP2h7|K69+zvurx+jxnRPc>e8 zmWx!$KbO<&;Pr`;64TWM50 z7lMw1@cK0ujW-?HcxHYOYhU)`|dxRy$CU!ZOo}S3foIz zb1H1k3Y+u7-ud9ye&qkuF+4RDRQE2!MHJr~I5Yi5B_#6Js550v*!OjgDzB@I1S7gbjceiTzQfl}P3fnQU;lKIUzsS)^jeT1-d^`Gm`q#hmRyxMvEt~23MT#?$ z-K<1;NTOuTH#K~{6ubhGsd?!0fXuFCF8lRU+_!7;m*9`kzKQ#O=*y0@C zEao#~=7UR1f|<-U&R=PK4?CUI#VIaGaeWtm`p-W9=5uEoJ8-lpY}N{6DnemgZFfKA z=&uUn>VriGfO!g=MKFt(W4*{^JM#oKCp1Wy3*O3|mq>LSaWJY`ql!^N)PuSJj{`8xF#f z?m$6`2h_|1*31Lm%-?^5xoXR1?zLv(-(IcR*)d76At@e2m{E!cRs2CK{-78C z**E|82f*-STQ>ZtHGEmc(eMKkrTEzIy}89Wdvwc&uUNw+#e)=faH14{`?){=Duu0V z*>FxsL%*9#@k>A6`c>co&t;1qeU&v6DPAKf)+NQ`TTAh`-|?>=Veq z81J`6GE_pPn|J63|M;~I-+URkg%t0Q6mORlPi-y5cfR?_ zU#9r&LfPh0eDKqccG&a2T`1dJio@Q|p9dGW3uT*2@yFiyFMpT9whLTH@wBA)0!i`C zt)+PJi9h)Q#cvnNHkab#pL_eS1G3wNvdyLVD_{BG&oJ}dE|hI9#rOWi@G%P8E^r~m zTNE(4#R4X`Sipqf61%PLQV`=V3u4^mL5w33_X{QNyS5hh@BG1^{S_lewk6m*=4~$S z-+RlKKE}wgwfE+jx4F2#^k0AN13>n6eYMTS{kaGK?K^?&`j*XfUk!2JCUM_p;=awq zP0Z>ZAXVgBjeM(-iCMis4m(;H39zpZ!XK4hzEyfz*;+53|L|LX3x=1sbPu?G&ita> zJy`Fezh(ILpJiax?+?BG4u)kUjk7@w2dUx3Oy_9Svdz+20ArTEoOz@8t7)|P z^xB_NBB*#f;b0iL!x*|l3}LHhvwOwPy#^Zh8feHg_hXk)?dxsm%fJ1JFEc>__HmqH zW*_ChbW(R(z8^lA(=Uq|^NoE2>SA_A1M1!4=WgTYZs+G)CWt4a2g(fN9Cp1Ke(?*x z^_&|`S@UxGeAsTAv8wDZY3i44$g*G0 zRJ8jly~sv>+0Lx=&UR<%mohxT4ha42S1M=V(9RL$#Zv8?LBzxO}6(ydjxt;>E)EWEXkue;gk`&Ie`)``L9(%Tvto`vX{q(zk|C!H*+#H9t_Wsrf9(l*FeD08!H-Pe3|4onn z<$w9>gHCw@%A=2e=loG6ebygUk{wz;#W9XAEPdLkD(O@HsFFVEkK*bnJx;IP^$`E8 zKD4H-;vC=dTH0uEAk*|Mjl9*c%YQPgCs8= z>}FDD0RZq{8I1L@f41pz)VlQrZ85FSc~@YIPUd^%IM$|0hgD}N1=d?epr1qn9niKI zMgrGl>ebMYKwF=i50k|>V7KvG-)Nh}0u4FTe#|LZ<(ATuYNa0jym~=@K8~e4WKVx4 zY1q@BRynWJo(2*b4HQt_QYx)Yk(FB{t98cu*H|bNUNuNwjdMY*PFH(~};Z2&qaN*_I zj2@6Py8>3lYS-tITzilf=@!18q0(R0t;`yKb)cmE@eg|!FHHFloY zX(@KS?0m)#jHENAKBym9&%^pLtsm1I(WW0e_>nDKXzV;)y~uBYTDEho{7_@Z8o<9+ zs{NF{E#XCv7t?w%&kK+ve}N$_LgT+g>q5gwdqDMC`>S+19@0zDio}$pTssRdbb+5r zFIGE*Mr|WC5~>zMj3@T_19k8X?7sp8N_k-_c%*P(*VvrS(=_{5c=@5RI_dK;-zl^9 z#@~MVTw`7j-7@QE{2fA|f1Iek{2bwT{&p(o2%YoLDzi4k-ySLWvW6_Y*}Hc8MHj5I z>$3Fcb1Y%)`L0LUFBs0b18U9@_TLGuu}7VNf;>OMN%;{<%+GO)o*$`3S}j{}8iI;6 zR^&w6Lt(0Pw<=ij3Kp=`wV@jmFpAVpU0ho_e*w9EL75dX{Lp0a{{)b&f?*X(wu8q`|toxyj&c4IXJ6 z4MqSXLTH6PQnYN`;d!qY5vArKnppYnY@eF9%bLd`s5n_v^H}Yo0WBm%Z&}yB^zIdI zk8SLbf$T)})Van~Y^59@Yo04C))oxO4a6-7Ofd_b&V|WQOlo%~ow`}){IX03i<5gJ zJY=xFckOF#XS3&N3nH>IkYeJf9c6Kj@j*?dHvF)l56*WGNoH{l9Gj9zrku$LhtJJo zjgP@3)@7w#)r)Cd2zugot~9C!{3Rv@Y=<@6=UY_}fM+m2c+~?6R=rR0 zmo-j&p&c)OTK*#x;Yw`*%KTq2P2g5 z47P-d=Ni*%uNS(K9`=+TxV9(eGo+`Pm?3$lm6}0ODH#WqGWVoliIxQwGw8){a`AVj z&mNaYSz7p?OBJRVl{5L*e)To7~w57^)I9Bt++M2&%70lAC8qR0d2QOuxW7(6< zuk0y)@KUC)#&q$67k%RqY2kwxDy~rRA8w~&)o-j;n;)<`>nfhXAw+gywaaR(ARg#2IUO5ux_^3^(gS%; z_fIs9j;-K)THVFsIi;OBl#>gkbA1d`2PYQ_e+u$kAjh(4=MG4G>@lQ#ok`!B!IcZo z&)~d0HZ7G&N)?m&j7-y~-Lo&rrcRcg;d|)&IHy|D24FLT1;z^%#;r>Wa=>!ui>7JV z5_Fhrwu^*@FiUADCkdn2oRZ)YFq%ZSU`j{u8joPe_;AF>A{1OxZOXM!%*6{aL|wtb zfKzBxss9p9gQr#QGM+TROquIJ;Ug9FtmdL;N;<2+Tt4bfbx6DN+ZZ?bD-Vy){qaKN z(D8QwVXq!qJnXXvM&D&Uyn@v){&aYOsNHcnppnPK?ktP_d|cy}YoG~QVXQx3E?Z;2 zk7efe@IK~IS@Bu!p}CAESug*bwnKTD2rJT--GA6`;~jULkf5>b73>{z`4%>E`KHuQ z{gk=QQf5&}J(MJ67KJKDABpsX5POIWK3z8GCdme!M4s6kr*~@679!$!`LdN~b2hX%8^0d$8EynT2OsF_s^20bW z!hL)yT5tH#!Lxc}VT$o7C>jo!rbG zg-Hv=3fg2;rA0IASq1C5>d?WaJ>?y*Hx;_(pxQWSqJUssv|kNfv=7Dlb+_6$q$ES$ z)budmjXYkMM)=OO8W5i~132Uz3&BMl?yO&;i=F^|g1)9%X-dVXXZ^M{U! z!R6_8TmQ@snUQhQyE^MZuVCL;XRU46S*>jqZ(~ob&$|pGhK8g8!V|U^<=hFfFB(vr z(R92!cii$iQ*1LtcI|0Nb)QQQ{Uzz4x7gCX4s{2uRgO^+ zq?*_-dB%`pMa!n9sFIO(_tow`?Uu0?ds2&bk0V5jcFPWnFxIBs0ksfSY9=CzweQXj zOUaJ3>;aVWb{az1DAGbw^qh75O^xhV+%#KQ;=G9!y)794!ZspL^`W|0Uoa{+7PqFx zJ~x)dT&x5L)$|tZTMU86oMp$>i5*m2w76@IU_oKF#->Qu0HRDhA;QR$Pf)23aYY)} z`bjRbk#qR(id4j)Lt%nWv=u%PxhWWSL-9L{)BAbz{?$fsqcC54N=+p0;CbqFa~$6A z!-nox*E!IM*=HT;GMI%|jMHtPaWmexU*Ub?qaia$o zn2K0YC1>geJg2x%V=B#Bxn;~f;rK6JX_!=!MZJ<}?hF`D)Wza0uRpgod#-UbS7b)x zWl$kRGkgAZ*m0Br2z8*SCk7})y%&oU3}Q(FLDN6mmKFN3Fo{{G;s?n5V78wT*W*Y^ zc#itaSqO;~UtvLv+n3~fX!4f)4Nt!0V`4~dX2Q*C9&qv$i>6A`-a_L1-0QNVrgM71 zjM^vtpTKAp#qs9>&o=I^J?rh2`&AUw`~UR0=l+3%E7T#zP~SCFi^9gVUnXkE;K4Fe63QRetky5 zTS`|cF3;a%7xeE@3ug0h#DelXtXNE*hr)@woDnSy_s#?24=`Mpkx4R)||`U6Vo; zsm#hJOFI)Q=7;Ikj>yVfWMww8GUJN``Y_%~nF_2-8!Ns{Knaz|N;$GpvV{sJURhRI z`+q|y{=0xG;v>_!g1(dEH(ky5e&_x7FZ}!`%hmD&H5Nz148M0zI!-7nflkcW<2;Yw z%r|YJ#^<0~p5u3#HEMl_-xmG~8VR%2YV*<4ysG_#?0_##+WN&`s3~N{{PE?)j5w31 zeOj1;B-?zQ-|X>?62wcV38vsa%8w-a6g<0XbKtKZKHZqrt2xq;x^r3)r99D{Rz~-< zIji}2$rt7RW^m{FArCewdtRl=yU4?)CM5N0lO!SU^I{~ z%P4%Lf)*K7DFL=rLDwoU7n8aZxleXl+`5w~9e=xbo@0j2L;ns1o)85DB36j?4owt! z=s{Vshdb~rAq;qfp^%3+y9H+^cGsjDa7SnW6G2Bx6P&+4$7ci<+pPJZu8<{p5K+pH zXkuCqjPV}XM%pgJY1NshTk`Q#{;Ddq(KuoD=n}xxMlPlqQ~!2vWAAn$bwW6nm+qm) zE{epOM&#TMvM(yKg~3YUMZve+^4fPY?M8O3(~_zUDAgwVORYz5v88;rA|E4;GjsAW zLfm>T=WT*1S_MI&U9`m*6~ugdUJ-^AEAj!2v1NQVN?=Cq?!dc@wb+w}(6F}=Sqy_L zitQd^aC2TeqDsv~M6vcIpM-kkn>*9hOrM0ZTF;C|Cb~f*J9oHg4rwGYU=pLZ9kI2D zJk^KlVtv7=+*sV2eDUENpiofxB{h8j`!C4VR2rwk#oejwE_W5nTkf1ExPcDsaf%`8;a*s95SFbb%|+n zjcjb2ih!;qfk)NEhuQHK{{?CT#A5BYIt<=pP)f5NzQ<9sXa+6Elg>RXR^)(s>7Efl z?cZi4J$lbNK<)XP{%sQ!-0bi&0csK3dT^%xRRq)_iN^u8tJ0g)?lPIEuV$APj2m*> zY90mIK9%mEjbr_K$mg=irhS_OYX8;%sJ&YqP=~h#K<)5gfZFB30JVFogG~#gomC+{ z-UL8J_{mO?akP`!2&f1y(spOFGL6uCgPkFwlpoQ=vf+d(eRe}YZFUf?@Ul1>Pi*bNlVKe|qWK`OX4LzsN{ABXJ zXu6mgUIwXbj+f2h3)FHJq)7A=re0UV2NA6bxWLxzxl!jOyiX zIm>qPV+O%Qi~XmKh{lKWAx+nCUKB?gT7Xd`=oPBSy!BkGsMb5I&3SyW2%|F0Nxe*M zXKjtUF#xXH+(g?n)$p`UEpf5cb# z57lghuW<;mC0B|lPO8|0^a3w5{aXawK4H~mEkX#}XzuU@>+!Y=+}NsVg4=z{QS41U zirFusY>5Ao@7Lu8#r953GJ`fRCxY#O7vo^tfs1jl?Wpu7mAil@gYAHf<6zsennzJ$ z2yGJBvOimPaLRk+ki~!VUI(Xw_j*h8UU_3++u^~$wtvdOwo4KN+b(Yc*dq93JP0@% zPXb#67ikm077?ZVh$f~@V2f-cErBiKinJ>OwtYl94z_*dB`YYJM~igQXAxa`F4z9e zF2)uzN??n6QsYodWO@?VhF-q~*tUc56k)IjZ5#&Mf%zh%EocD-X0PwIXC8c&Try*B3j`|(e^q) zv_&u+1kn~TrVULZiDE=(FzPN4>dA!@pU<%asNi|JH-ocfQ?(dCBfdJx(uTo!ii~yx z^E4nSyA>EMPJ@ORfEhUMSmZ@`5udd%VLqXl7n8O-sQ`v8nl=#(2b3JZkcy)UHv_{y zhZ`ZZ!HpBaaCnm&U>6MZdHRh34BIEeI4xXO3H=)b7(xhh84NuMojw!UnVkfNC@-b$ z86Xu=c4Zx7X#y!J<)jSG@ ztx)M07`8|%`@7!3uysQK!}blqrNQ9LRqXKK)4J=UXLy5yVTU~K8ImM`A!Z%KOdpHS zipJQMV-P+zN^#8z({MzT@*^65)^Ke7k}`8z0>k0;DcuMdj!whJ!Elplc+c!?6b$=8 zv_&v%qbKRJ2!=hEYyWx|W80(`z!3H1jf)Nadcd#?qcWaiCm9Cji(uG=DKT0cI6Ke+ z7}B=H7j23{-vSJ~*uz9HY+G$MXQkp;+Gb$*SRtIyyWZ`thjqChc)bJN0D_`(bPbF* zF+9ix$v!!GuN%#!RZE<>cW-bQ9a8ALjb5~d^;a(+C8qK*hS-E@1JDp)S{%*0mEeQe^MH`Q+O3i<2FBlO6L zYA;U1QAudfl)DS^J>s@$jk`rR(2BsW3S~Z~X*h+Zf0^f}xaVMXbQ=EHglTw>)9|*K zhW9CE;xxR+3k`Iulfbsa%ZXq+!VXwF=h7 zJX@-RxzuU^+Y

hpUbfT?mG;oz)og?2E$Xi~FH!~54cWDa;^o@Z;-k$MOr%w<{y zp%3%MO`L|KyrdwEAZLB6X*h~V8BsvYm^@E}9ch>0c}CYyp69x0_yCz*p65x1;CZ5< z!0u+AXLNk!d2Tih@4EJS*G>Y%{xus+!&~GU2g4z>aWL$t^ky$|ya5;n121|LJ*#=N zBMhLa(lO6-aNO*#ca4ML;F{ohwyyPFJiIn~o;(;T_DN!3*uK`maKM{+8F80~0EU=# zvI^7{Eg((95nQBAoQ5N!lpoQ=w7KV*(~{?jykoi%&+~at!@G!9cv5uex&vO_= zTf~?SG>PPzAV!3irs1e3H4e2zrl0>byal7 z)DplD4Fz^L1H*{LTTR1z4ki8LlZ>GSn-e|54ll;RuuVzhVAxgZO_+C%HvmHl8}|%{ z4R>EgIzp&)3=G>OrPB@@4urb!~2K~5srZ2Ac(dIh8^@I zeHOv6?{Xb9T#Ox)Uhu$BPu{qk>E{oIJs2Ga!xl`5`JxT{x9!U#8+%+Gb$bDNMur4ac)S*5!U+!+~xHAxy(D-o)@Q7vvVxaMcp0 z;k~OJMqB7--bOE4lcwP)F_n)o#3o$MG+dR%X?UkW51Kp;M}w&*G#6`1({QvDX_qq% zSM9}VI4TL%JilppN7HZ$P5&0B;X}5Q7FWYN6Q<$)`j*r10mV$5hWB{^R1LC8VB6*8 zM6hj9<2cy%ppAoVPo+1h+yyilY+IQ0IM{Zq=FyJUwhGow!`t41P8Ptn9aYfpdnT8J$+4wYk$UPC`)9_BvXAx`%q|+dFEPyRCO4D%ElNyIwBGb=*8r}`Y zQ(O%nKpO|!ZeYI1Xa`yx1dio=(Wc1P7Sr%9Ujb0jde3vf-5D{Y7faU8+KrAupc|7z z-RY`{o@cl2mN-C`2EQF@HqUc#%pr5g8}mHdnIm-z=nT_v3_S^*J`)=^aT<>DQd*24 zrrp}}L=h#fM970p2W1i=b6YsFU{!s_R z;nCoEwy*MD+``~&0jPUbK*a$`3=BJ0IT#LkGp|B=JOnVrtdmusu4n;i8jj#1ZQ?W> z5vBZyCZ^3j&-h-8wc4?$QR8SzH{y9d?`e1sod{2g)9_vpZPD{=1$`DVrb{}BPd}5EwORW-}7t-<0&%Q56l-m&rYy`;xxPsEqI=^E%8O0B41m0o*nFAA{e%; zHuF5GIF_~<7(R2ilKFnp?oqe99tLR8H#`#JjSRWL^Tc>_h9lUqd3*B(Ak`8*&vt;( zKDF3@-nI@97JyJ%TeXA^ZjlKXS z5}z}?7*4tbZw;3Dju*ASwiNZSL(m)7g^07qI^uj4BhesNJ!;nx)AoTr@S z%TG?e=R_zzLu@+WGF;kmTK=1{W?#l>K-zqu_Y8E)et4GuW_aaGcL!O6S5KGz1>6&$ zUvfaV1^ZBiNC3K_cc?`q0NpU&PU)&PMFP+*eh})C;tkL*-QC1F8 z(1+AL4(J1DvZ8~N0KI1!CII??Dm0iB0lfol9MJnJy-B^U-N}I7rXk~i-VLl4J9En_ zSO@4GZ$bB<1A6OF0QA8jN1_e{1N7d(0O)-l4A5JLL-dy<=D!Sh6966Y29qTEdnh~? zqQ3~v-){iuh$!VpG%;-gbYvT83D6N&q+J<6?<2BtKyL@p7Ki#_&}R`RTQ1l3!7wf& zqXg)vCp8YWM5doVptpnZ6al>lZ5+^toF*<4E;2fR766^LCBA4=mfytK&Vc0L=L)j_IYD~-Z|)i-Ujjmpkv~xS@f33$V5O# zZ7D74k7>6CbX1TsBKnvy0Xkxiw5ky1RK}0Q9a|+XO%#?B4*;JG>YN z^fojAy|aH3pbwXoVFIAHL)}F{?^Dt^ptn?dlX_jdlL5U)VdH>4u$o7`v#wRJ4$%7~ zr3Hg!2lVd#0O;)ljzoP32I#}(0O&0!2I$=b4(J02J|X2H06O9gCP}a(HlP6L2+rSc z0O*J)i{0Cd`x_@YgbuPp$*gJDq7`UrE2k^`VqaV%|9 zKyNKi1oYm1x40n&W`N#SowD2RvRh{h`Ob^bUkd$-0KFwZho1fg+!LTb zao0LP7ikR8MH&Nik=6rx%K-g}yP8jw0-_K0xtqK$=F;ZHL>IlkcRix_pvjCT9C-#5 zTZRdU-V1dX5xoU%9MQWfy-B^U-pPnQB;z=uw*#w17kvQDL*yeKT1$1Xb$72L`e1KB z^xi&)qSn5E=pEkpaRodWq7U{tqPIz6h~DE(Ky<_#Y?3Kxd@dk5g7fzqAUYyS`4LS_ zn-Cq@Mp{C2#1&~*2GP5Sb{x@%d)x|&h~5wSECS_#bjWqMCk%|pC?PuPNsU7-k?H4; z=tI-(=+@m1OpPOYKQLcpvlW8RiiYSt)hYQ7_Bf($`0awt|zo2_U^zM2@7ikR9 zMH)kNk=7&n6L%?y-n}ci=xwvM2`+kX_XdF8;>Ea&KBRJ4(e6nuN}rb#UGyO((WgdY zE?sEjfId*^P3m>+P6qT24H*aYp4B|+qPMMrbuN0>ThOaHptpAiKp*aQB+lda_!W@xCjCzKu0~Pai}FS{rmyF6O50CY?|HH+R78JP&^s4b;M{W0yZu7G@CW*0H9W2I!<$8m^ z8=~oj&xyJe}AxM!Zn5to=`zE%I_A6!&>C4#jP_7>DAvN^erR>t!+&_sKX8 z#luA(HAZ}E3Y*|t4@gQ2hKs?s-W8y@zsoVCjnNwvw|HZ|b(;r+;@&QY;toj+iaWds zP>kS%F)_!8hE;&#PJF)s6eFUPAJO=8IvarTDZVd!7KgZEx+??4Jw!VW#l0ZfA`}mU zK8py~b-DHyU5rDMUfh7cm^W^aGyVLbxD|}2Xx3e5>!3I=Uu1N+GeI$JOG2kjQJ7mn z@!|$h+@<6Q#j)hg_u~y0ygTj0z(!Uz?TnDtQt+d(H{X=9Gaz$!(M_`#5qhxbfZT@= z_Typbsd4m~*tq#gtC}b;rNszh+O7BFp@@_b1;mVLKOVx4v@5kAuZNT`Yd>Cx48ai5 zP+<2;?8j?UFi_Ir!1ncE*hRGy_u~zCF%E`(N*V{lmP&8JymPz(7zP6$!Dy>_)GzIY zN*xdrocHFv1q%*_y#ya0B1-uYO-!5i;~|lu&*D0fQM8L%BGb=*Ki(i1Pm$41V7@pY4pFuYkHIq;zyMls;Aork z0$;Q#@)afnibhO2on|<{0T}kJHrtO!#j&(a{L*G`hY77eKM@QEJKX>~ps(-wpk{MZ zTMJ>F7A{Ndz4-u!5aLOjkp(p_f}Muv30pi+UJ?XGkh8wkH^L|)WkdlnV**2j9ch;V zhH-cB#Lwc|$n3Jfu!~v(7^0!T?q*2H(PN(9i-rQvZM|LBl|8$v>prx#0n;Q zhAsFX2g4z>aWHJF^d`(Z#~Xkl8OJ@tzSTSmhC^tobPNoKvu=NL4u-?I0EVp{!KK*| zz_5+w85j;o;-2A-5OpPqdxj*5p5cxtW}>d~x#$_jMs463BBG!sc80{~!s#@KCR$Yj zL*yN4BVhQvKa1;{osEKFFNn4XhAr#$qx%iIq*Je)b1}9|dLg=rdh*7_=db5oX_G^`^e_xSPUP`*fAr%-Ht2nCTyYe z9c+bNblg^~X*h+Ze~X{R4NluinSave+v7wcu3FrjEE2Jz;^t(LuoXYG#%o0r7cH(j zINdxDHzxyCK9rBm?OVKn*c@rSJU+7FoG@4ubxDLTZ+Qg6R5Rtz}0Ei~0O>xzBPD^oB#1+$BnaO+y z(T-2%2gnNxkgn3e-3$7}o)V3VC1n`{?r$>-K}IRAih5GxP)lU``A_Bt!FY<3`8G_+ z`7T0sFEC$Zv8`6irP|I)E`B#bzBt{q>P9@ zW=wHa#2jf`$5oMBDD0aSSJj^67J#h1$j@-YjP@W8^_Ts?Pw6kqQUl#Q1HPtz(_Xda zOx?!W)?I9sMhnlJuKO^1np;r${nY8YuWO#J&)T;kEwhaY%UWE#HyM71)%EZ@fF_-D zDffE#?OBEi@H?OiL4Of`xfX66{PtCPev{y2_-)gWaro^9R*PMad)9)tthy6Sbi4&z zYiRe>=ngr9-@%mQMhAi!xGn=U_|=_=2EQ$?mQ?GzBr%V9z?%TSh&Ned;VQ!fzX&c` z<3#vHL@7U_iD?u3BHKty@Qb)2?aII}cPp-g-*ymf5q^h3pGCR0T(0eE7{!oLf?w2= z8i!gU)6XA%+rfB>@Y{nn4!^qhQe#JvQC;U4;Fq=~zGzeAYYX@taA%f zieqV;gbzT|%0&3(qE4TqAw}!Xy3f)2GnWjSb?Saj>-gOGX!fhCB?J6o;;C8mmdMCN z_(g3gE$WYHw}xL-kTN3rm@&a`;p)Y$;Wxh@@xN{OEq=_`D;X3%;}?Pf3xja?SJ5cj zn1rD*784e(1fOHqf|V^%>n_6Jqf1xZuB+?=t}S10Zn~{^Vt_(-2#>>U3r5BR6uRq~ z;iVjuHyLhwWE_Xvj@3Ns=?tiJ{nC}V@01;CUlEY@<&F?7OxjGjTMj_m|Fix`aSkKk}nbP?W8nZ?*8+?4-nNi@XH&|2!T zXe%~7pz!m%3@lua(KTI$yTI(?J;aOU#5y*)2TZPx-7qfeEOwm^LKw&MRuDq5!C4OH zg$AbUO{FutMrNaHz;r!1j>)?ICG`x;Zjc??XYQ50tR}i{F7~NhoG2_dHCWQ5OTY?2 zPj~e+lMX9iv@Dje$)z>osYVcU#9^ODOdhk2WgtC})-7`vq9>xOXu)a=z zbl0Mw)P8jBN9(TF#oIzrm7UEW?|jX#G8L1>i$V!jUr4klJJuus&c6SEruOrp{;Fb~-=lN>aN)wbXp9bXJ{z zI=_%LE1jsWhL~8Xc}lM}lINc^>H|k=FE#J-cV;mq-J@$si{C=dR?fI@6Sb)0IaC*| zPX(gs_k@c%zdNWqAlAmGkcGDcf1BCe^}NkE+&jepLDzQ|8P#B;78Kc&DgA;EwOFW>5ez|c_f6tub zE_uBm%V9mVNwH!ncsQb-%yM1P(k?bJld^D_OKbn%<>xZm!%hK5dK-3R>2`orqh z*`e%!7_keFb!FYuLunzjx@og$rb8@27E`p2 zK9(ShDOyK2SWMA6y1`-!)&clRPu+^^OMa>8x{oUN+ck7FI}NOQ&P5s=L!8Q7EVcNZ z{2))a+xHV3Fj0kT?}Mlcmt?PZM@&4pBWAjIb!M=qWUsm@9$uo?MK6kK*=J@FZ@Dkr zv8@}X;S{N;&lDxv3LUyA(E&6`xhT;NeM?dOZ?>;_GiE)2-W8d3D%Ev;&@zOl-=?T$pRfDQ6NIS{oPuvLpGp zE!l;@1!_usqsCbHbiDlol||Z&U-nvU=H4HJE!76^Z_aNQv0JX>DfR6F2Ug6O^nR=Bc^LOe~Jh^97pVqLs zTAyKnw{gs-QSR^AfGTGlgXbMfeYTLuV@-acQ~A2zZj~%}ql~h6Km|XEA~y1XcAV$# z`Xq$!09uM3kUKxGnCD0o%I%tOUmE}SmmkYp8wbUBl#;PT1$kq2ZhXQOJ*74aX% zpWL>BA4r~@>1tx}JmDYQ&PtK#RE)W8k!jY7R25@q(y_7dP*x}nrZbo}!LsOG*e^5 zJ-gm>=IrrNd(WYpKD}O6Emd39a_wLS8EnuR1LdEsS!mFV%_0^vE}Mqc&Uy#o^#Khw zL+#qbXuxJ_pxM!S8f!n_dn4jSW@V`x8_zL6+*aj#5%D78-nen^jeBoItoG0Hcto|d zREO@Tx6YtClGV<#j`e=J)hyzT@>d#3PeW~QL!sRCK4)tX4hyM1|35zd7^7AFeDlOg zp@$3huK31v4?rD~>}QE%F~i zeKnK*QPGV(^)(o}>E5d3m-%Cv&SKzBe(Al+GvB?G-+OOKD@uy%Hvdo}PD$B^<_{(* zR$ny-?YW{?Vs!Fvj-7~4N7K_vdMeY?a(e2gr>;NsgmXKQr4beBcJI&HtEcvL z|L<-rLv6=IBP(a)0_p~IBBBWi+pj#sTi4%qAVy_&H&puiqOzc_wY6ua?V}Z*ztU3b zv5och^`RZJVh#1bz74Tv(G&rq?$@`WDTy1&?_b?||Cj&hy}$gs|Lf^DAkj~~L2Wm_ zzHLvhp8mdvhRuhn(?19U%DeFW4?>Kme~^xx{@w>4D&bD6TW|XpkNuy&{geOZ zK|Xqtu6_J3KKzw`@(b5~VykfqDTgsT3{PwIsgM8uAxoAF3OOziZDosOKlKe!v|Jo7i|=G=A$IO98ol05uU(vOLU#SQg1gds zVA%H6U7F-KZaT>!=8mz1^4VEOUA6`D_|4~1uRbZ;n$Shn2ppu1F-43(+!#K1CEzsC?FuiSWISZLTdD(UXVQ3ToP?|YEZ3PRz=jm8@uVvSDT z3i9=*H{bbdzx2;P`*XkFc*BD>*xVPNB{JAWC|x3gH$U;ktv|f>e?0wPG0yW1P~Xxd z=%K2uu5DWbm`6x!uugsHhHllIi|ulo$O6+@Y+!D+zcF02mp-?T`|QVJ!CC;`zruID zbv`^2xWZSI-d{aT`rP_z^78JA$g3HreBX%l93^gHMEz~U-bRM*fQHU<(Q8@Hj12g#8gS3O&I04sQCiZHAmm=C zn`CJbTfdYZSDPjbV!#q^jz# z);j?KV5k4%LJ2hAUMaSku$(aS`Mz)9UsK~tb>l6 zI9VUU`LB9y=yN*kt)5=%!!Erp5aQw?mu-0HZ~tBDoz2NUU1+^A^^YF2visireQNas z?|=8~ND)tBZc)6u`nHXK_lv*$zJJw-MbH-NL`^_(u-Vlw{rQK#^8R1AHue4UO_n+V z@>hav`kwF*;GA0h-0%OR52HQLlF3vVh}Pdsok?$|(xf+2 zYxE{MgQ^O-FtYFUR)4Rz^u4~g-sDT@5$Y>!8lw_6`CR&)wV|mUxqY4%*?pcC`F%)( zbL$DNQ&gMQsbLF!Hmh8zRNjy%i4`f0${Rs3v`#3E${P|Uv2u*nRKD4)I)nD==|QJ; z99fH9a#Q?67E=B1`1%hGrym`3R-5JY*+EzNmz#r`;yA=J{lsv#y6@HVjn&40y(R+| z@Pj#osZMR(7|d7qm9q~FaBF%-IWr(CRv|3*acA}Pe~v82!cZ$d^ysjIJ@^C`l72b+U56fca^uYEE6)trh+WP-I#}YT`{-bQ*@KhM4;E-S zd|Qrxrbh7f5WrWQTCM5L*RD-JL<#**7W7EFK=}h25q)L|)kKKlb1gv<; z1suv00SO1>z1%NjO;MG*v0)KYrkW) zynWCw4}rDYbb#hePv<^*uh}5lge0?1!q84-RfeOx&i~UA6|Z4ALyPV-(&hZo}^ngx@#Y@ANwV z(;NX2bP}_8)ux*;k{*v5?jGIfo2qZUo~6U2#(Jmy05 zTs!c}AZbJ=MrABqJq_v;24t9n_@*DnVP(7=Dp466r3G6sl#I@P-`izUx$o^Np_2qs zEriCaYoVk_%L^^zz(|D%X}>Kmv=j=JkS>MxrLS$KaLqk_!HkSYiFzm^fUKv>j`Z`m zj=+Y+G*UmKIZEpAaGwfGq?Gp5=d-yp3_$)_XV1@=g!b8Oe0JbWtxZughjj1x8PYDa z%RI;Wdj>A;#f_Rp#wNtKiW5g9z#6?Dp2f*G8<&Wis0uC5!F;kUW?L5h_Zho2Zw||V z7A9wWX4%R%^T1u?6N+pUAY+drTNKgv_4+sa{+xf0V+xD?Amod5P<a42LLo*E&$vV-4Y*yM2a;Ek|AFT`ayynjkIA+L`TJxp36z??QqecYxNupl#$ zP<`UbJ?Gb6a|3&lI4HX+)i%#~*h{trGrF~4^-j^(5mOtRB-O|0dt-efWK5e=L<5c? zZeHdo`e%rkFWFOz3Y!dP=yq9!(Qt-dEyG#CY#cG1fwFl)IG-W%6mT0urP=umJ)}e5 ze)Rzby2u|oVFM8aB#R!?p>YsMAS&WlGZ zXRZdAy5CqgEyw;YoAIPsU2n*={++fKtkzzfmgpPxBe&Xzg}beiUIcw>mGmMMg{Ib& zh*Ey&t(M|z()VnWpY85qqtrA^`8~#zF@&Kt2;F3%x-@ zTZ93P)S%rew_zrgqql-&9WTOLjo&4UU(h(j{1g)e&TCvA@U^GM_1sz>(4YofW_C=b z#271pZ$h6L78ag?utSMin!h`16^K4COA z1Ij0i#!kTbgwY5%-#r?oqrBymp`fr?mLLWZLzpnlKu4&SZ6*lQHC6-FI#!n~ylc4R zQ)R*p4X6_qT;?;JiHx2D52o!oJ)kiy#La@q7B#%LGA+gHf~19;tlx}ttekbd za~4K1rUj+Gjiic6VYkkH>w`z`APGZo&HHQ}-EuIcN`6m`R@QrguN z68pq(s@m$9xuJ_)jDHCErp)Zv9ngH_-D?cG{F{-11E^k9n}C^p`J0rR?H5UT#|y)+ zsh!xk!y^X1tKqSa_a!_ot5R917l8Y%UIRq@}Bl>+rC#uw7udNFanTQ4T{ z87G)KMX;BZdU-tcic+tPr(RX+)hyLm;I>k?Uu>|_YkGx0_h$`eKy4VPHv@AAPW0?x zhEm^?hV50NZ)Edee#O_=BeRmgvUW4AuzA-lfoI`4caN zcWJ&^vGbPfF=nW{D!HvB!iI8>u^G;YN|OKZqUYyMHn-QAyZL3U3!b0**^FuM>87$4 z#;S(ZN`VNqi!Nw=w08XYUc}s+A}ETCG@yt!8o2yo=O^QsI&A|!^{`=T8BC3$BpKqw z$Ayxb;(=U&;t6FCsiAgu3<~k=*$hFmV<5<&IqU9OLy$r;Ye%Fp+kl`rubPbTF@sy( zwaJlBx)2U%cthIf!?iv(zwV?a$Dn#JhFujNoucCK)R^~Ag)ZlFQ&jk(6aCFFKjlhj z8vV|Qe&)uPp(y!SKPNCdbp>^vj1F&6^F+ z7=@9q&zJzP*HDttuc727^h^G8pd0WwMN2t>j(gIZgko46<88c zevHkEZ^<$~EVCICSS%YGR(K@R*DmKw%tb-Dsg;w7-zhRT@w#CvY}OjIT}6r8xa#iM zPOap#AhyVMj+s3xZA8j(Nt%&YioK{ZVRj&(~oC?zz<2`6H&SyuWa_dystSGt#{`# zr$%G-vA3;noZH-5Yrd?&KZ9n9E~W^9u?&n&<0-^KjD8Gj(DzhB)A8w8cxqMa%@eCX z_mLlc=A9q-$j)c2T&sGfaboqx2Y+SbH{SVsZ~Lj!`nFX)P1>LS;je!F15f{A8pOE8cEDF$pPsJ_@ZF_=Qvwa-gjkvProX*8X zq}KR{ZMijNIJBh(7HI==tISV!OgL!jR`qut?q=r|IzNg zr=+^?DXH#zNE+?C?BZkH=T(fMDjgbotu}x7@yA$|WJzTcL$1N=A9VU35b(SZ0;U1c zBesqBNKjdP6h+|e>nOIx10du0k{076Yb<_BBb%YISXV-ZM_jHWcq|?s#bYE9B6&E; z1?a3*5lq>!$1BYVi2gewi3I)}i3DNtcO)>vU`FTK-v&PMzQ5xWxqPV^a^fa6Lk>xQ z>xd-r2_)scEZ&GYNM6iepC8qILhL7{8Y{(dnW~6fLwrP~!QY}n;cr3NK!CI;oiveR zf>KjVP-=?ZN)6Rq!+>qO`(0oa=GK$$6eL)Y3vL7sJ~s~?wF1$V06ng5=?XB>c>57uVR3rCQwHS6d^ zF@JW7tu;NuL4@fP-2}}SSRanTh zcA1o`1R3Frc}#H}_^u&-dTY`$t(92zWu1+(7pXD_?r2t*I6ISf2+&s@Pnj;0P1dk)0jwv@mzlj_jGLSh4WWB>d z@J4dRd^0m%8~R(xPH?_qgD>_nY;nQgaEzQ$b3Q$^+K%E#k(G$eXy?snFbBXV2E-yt z*_n?z3-*I%FpKp*{O$9t)9n!6rVzL3@OIVBu$@k}TC>{| zi0}>@d9YI^W27vXOc^^x%JydZ1WG1A?e;R826Yh4H46@9?)2f*RI5u`xF5ZzBq3dM zv1FQ*bx8}$_L9VPEqKXjRg?{pZErN1kNOaQ^O_03B3Pm@xjKWZl<|ZMEy@Kg z1Q>+eYjeZfU}beKs32-HpT0!wx$w3EsO~SLcS$BQ}aH zHWu-U51jd4-l0Pq?@WPXt!k4!4=@98Ne0{^M3k}2;0wa{^e?5Ykw(?$;27f(GQ|7B zIS#89eN{)S1eUIJ5+gh`37+x>e$c9(H(mz8J-Cf^ z9x3ngG|&~(o?jkO+6$;mjXs~3;q$$LyT(Gq?$|3tj7~BpI{PXokBb4d`8aI`)PmlG z?oG!lmn0Y(H$e>@4akWd1rZEO>~vWU)amD2r|&9Db^0#vbXl{9NtCuj2Sl@ZN4bE* zI-k?PxzPE%qidv<-Y;NFNC&3auOp6hb^c^o8fM{qj20ROqkc{*#>8IPQSU|$G#qPl zyMJ>+cN{30b5<txQ^xYCC7ymEOPVN$4m@1Dz*Q$gw!A_P(TrYc}6Rml)ILPc|d6(&m)F%p> zviTY*+XUu|%Dc~zEyY5C~Q&rFhTDy zpok~EpnQooBi2It`Rr4##pf-65DsixVUJv$!R6%72hj5HdTAlF!+IMMhZrEWUI-4> zecBAz0#$#B%;GlErS&?=!v}L5-;QICy3>)8CA*x?l($O-;(ufQJwU3ve5!Nws|{EXDdXXvKoreyRo^+UPW$>k2!ZVrZFKEvl%k=RnH_p5q8sP`lGens#5^CbMY=PMNrM9e^`uzJhy2i9YKOMasDm#0gUSjT+N~Sw_wt{^#tzS-~(4fXsfPi zhYWNCvG!Cu7but*&s*G7?G^1hQ<=zHD{g5}$% zaBIXi2eg>X-7?c3+hJZaG4#-)u6dvqk^R;lN$wi77C)1rK7N-g4irfqUz^DTt z4iN6-1935}=Zv85j39_CP~`c14{BoB!?qoVG;kZ!mYio$u1=fr=ukh(xAZe;LIX=< zdP2FUo*-bkBEyc6)D;lpe;duEaEa-ksCdQd++NP%QS;g%J^qM|6 zyc0*G+J*pk@p5ZE+6I3TE0K1V24o9X5;$m9Qm>#>mY~aJ$w4f+`4{BoBBk?d(a2wN> zd?5wp)#XN*=3!@=VGbM_W14&Jzkv&f`JM~Ba{;v@Jb-c1c; z+>5dEj4s0x0V!P~c%au27bQl{3`wn3O`^1&Ks@>4>LQ&V7p82QFs7DwlszMHaRqD% z>1#DImmKNpyu_XuL%z7u4iqSSH~n9sW>f4~5!9O}ZnC(lbW3cjx@3Pbw<4p`r8+R|E@%ESciB8M&2UhiU?Je9ZjaD2!%t>sZUv`wSC^&jvss*yQwEe>yUyo_y|YOxzTX;Q(cxC89KJtBKH!O^&` zvleiate17VR%8?&MxgR)s3a@oxazsg}pja5A+!UUUJ1vr>39e z*eK((VM|_IN<{21dl`I(sSQj5!R*~saQHV1 zgBN-jxRznN)S1h_v^$D2n^b)pRcHCbJ2iB(F4HoTLfxfL%iH(FSEvmF)JChfd1jp(ms)Ya`-JeG)qK?*Wg=A>z15h!*46m zy-6=we{dWaty19;t3w#!Wsw(i0U!h!R{y(|Y-fBc92aMYORC}9%5Mv==1ck3@>|0z zew0S}E#h>pTNsU`x1-Ql zYx!aIo8;J#Z?=4HY?BaZ7ezA>JvwWo-C(Q@yR?IXgz}WiqJ+h=clxR9zN?xAhZK=R z&iRZ=&@-aeBJomx=>A*Mw(CiAhtH5hHrv8p@jJY-Fhj1y!q|{(iio^*w1zyjHbvsO z=#UBqnUjx>c-z1fV|Z6iyH;rR`X|BnS8lvg^QAbO=<4)LcB& zU_&;ch66UH_;PV#Sq;k!cKJeR*1wSHO&yJ+zPk^BOt;{MY#Y|xGj|u)1@2wN^e7lc z)^^DZen`V*wETf5QLRsrviZ{Dtte-wWdp>zi0{6EVB%mYwk8OUZ?oV4-DSfy>z?$j z76IT%eNXxpbNYMIK~FlWBn-g%@HS5(tPY2uCmmMO3KOpgUT!ORzzg0=s=LB1RcDRU z6+*;<=h3UU!;=+VE>S(_Un4zZi+Xnv(1$jzX37eib?i;HzJgYsoEgC0JkW2?H8&7kEs6A+w{bbOrUN*7gbo$c@GEkG6uMt{tSwvK9thniS+PxTxU1JiEXeEPSu8y7=f2~8@q;1+IT)|Ho<|GzO^i`xj;50wFONVxy=3rgw)9Ze& zdUGbI*Rd1ppk|O4>m!6n;1^Y`DdWymlApd{u~=H9*odW+t&SDsF8uy`)) zn1)TFgw$8QggXQQt&b-$B zn2azP5d?Hck)uHk?emGk07+VQ>&7vi>%n1a7FVY^EUMOtXFZDn0h}F;0ko(oPFi46)hEMo^qCImkfx}xDjkB+DG5S>zyvE< zif9Bz5q}c|_z7((22j*SsGJRxBeAi18U_%eD5d`or`Gk#sd4tp=KFPyK0O3lr&dot zj(q)Oy6}L`obl)`u@y4s>4xQ%NUHdRg zsW3DK!^xBAbE<{FN5KG_&_EMf64pFE)PS#XCRgL^4f28>p!4C>s!;BOO+jyqPqSfz zA~fiHr9lU^lSjO;5odU^Pjz2FHsYZFs~B-~fSZpvsNQqL;pDqV99LP22Had~Nz1A) zj_IVxzv6gtyewEIYqLm8=bBt+CRH-n)~Bi5PHZT83a4M!aid)w;a~;X*l35I@WzTs zI;U#5=8xJ}ipgE6Ec>df{%Di)N_)^%6BnNaY3X&k7^i>06P>SfbWpzMxUOzF;udRA9!I(xXT8Al zb)FTEx+#Vg)ebWz*IFpJLGH@>3LnS?G8P#!Ms-7c5~R`6<^+`$+|w~rko8rq%J5ZC zd1xW1j^L1*MpXb{QtfKj<=Z4VY1TqjKGMLpwVdn3W{#x+Q(0@(gLZ{I)YY)|M?sj? zJBPs9p{7zs&5&%$m5@q;xjeYR4uK$bJ@D&uJcJ9BL9Tb1?t{-Lp1aXKl(ZKGOIYl8 za1R9^AP7p|gP8bz&`}MuF)dwG53*v~$OXz>SI73aK-m^ytUkf59UM@Ph+w{l+=3R;o?`LT`O{C$&<3De`&Nu{nGqBOo8gt1cu{)5UsTb%B zoPF+)Cf(JBEYe7zC3o995wSKIUkMO9L4C|(!&$9Wn$9p$akc(njV2~53ti&~S+4^8 zCD6fJ>`l5pIqIGYQj;oV3V1Y1A@r?-*{KkOIH-f+20dSmAdmH>RAuZ|wk|ZaHM1EI z9H7x$!-+`zwfz;ZhZzj_C%4=Me4JvL_IAvX|HC(4byi$wPxGe zj1Y<@Cg0Fn&I=}ifM{Vg+;XcK1m)RD9?1wB(vmEaF*c+nIb`R6`?pC3S=AS)8kNiV zwA~>P#EQ8U0P$K9G!0wu+p<5E!J$AI{>BvPD)-A6)bLFY3el%8!Yh&>lnNKEDY35J zHtTpvrhh7#L}%TIsn%DJW$HH^j{{YL07ji;H-eq}r7X769k9W>0++H~1a)3ZpJ54> zoG0%($Eu|7*m9YFx7p0{I-}olT7CW9)aZARcAZD4P2Cz7N~9d3T802p)+9%a%@JQn zz3))bt?f{oQx6O~o`ZJ8`M$P;Nhj><*u1xBH))GQ;5b8f*bVrb7W%vVN$-$L*Ebdk zf72qBE`L%!`0o0IwEU8qRz!T$GTEZix;fFm#RNM`N}}IsQ93fT8|;W)ikW~I?PfEA zgXn1wPE&_ea;z?^q7hcR!UDp$*9?Wn^5p!myxB>4x@G`g)ti*Z_5|fciv*@a^^&_j zjBa@Xcsg5Co2}ZrqJ65fvYK+;jB>ToCZVS9Y0*BX#)xSskJU=G!uVtZ;d!Hj;c24- z;%TFU!cH;k3IcdaM9`_u!=%{HvDE>myyI8uV0uA)XX;5nC&?Bn96Q*DqbkD`6Gn14mj)F)a?HKA=Y2<*+u($1^) ziq@U>Xk(W(1Tf*zRIY!ivgY^BkJU<(m08#Z85tAc}q@c9xk+q z58(GI@hi43W`l==N;%KNvOTmo>Xn3RBrNLT0uMS@)RFI<<{2FOv%&@JP)!D~PQ!^R zc^*937J@*2as+j>5Q*Q1<9ZFZF)bX|3nuDv;kaJ+s4m*Q)_8MGM2;WBySSHqvLleL z77pWi{8=Lh@m?pp+5q=Z(+Hlg1>ENYc{vPtj`$7IggklB_`M9`m;ET!PQ~~o>@jW; z(j^Nf4_@|L-A{bLp^CmstZEZTQ4MT_0o?$STm2+lP#g6-4O#6rJLt#4h9Mb&dkyWQ zx*Ui#pGntA(=A6i&0P(+$l<;Y!C5c`gb_hgmGN08x#}))LjR?uEcxJB5GOjfhD0Q~ z2auQBPMX)DL=L})uBD(yXhC^GD?=C28i>k?#i?nii{93=i$-J!+z{y3=)NK>c?7yx z#gZw<6DO#8aZM|t+jF&#Q*pf#P?`D!3S))yeiu8W5JxE9q+>Lq)sdNS7rdX5bDL51 z9Q`!y(7PL|-|tH-F?vOLDilZG!Z$LL<#~aKsO9f<`&(;xO_YaINvg{D=Ta4$jmidX zuPgO$T7Rsbn5y$P-zxTRyg9Ib-Nj6$k0PT@RBM9?-y*7Y;}#Xrc=%g{iok!vrp?W{ z`UTb-4nU`c{0Yiy3W=Z=jt5HAgJQFP9z$sUc0zD zYSk{Tu1g6gaCPAyp3-!tex1dSG4=C0&0X|Jf-`jrdqA zpgxf*7>=Zxcsgi{X%l%m2uk0Bm{_*v>2+G-=^!hX`zzz=D-I%7@)6Ev93ACjoS|P0 zXdhwdjG@LlXKZLk!YwykIzu;%+DYhew+I>|&yYosz9xqLMjuPIy(f0QQX?1wimf~w zH%E~Yjpoe!5-^W5^Gm=ir6PwJH8wJH(BusQ;^lnQZpzFrfu+5edDkiO5~OIn{52UX z2id8$%`_-y>zjDOSN&J-PX*sU&bAT3{4Yy9HBuHJY8{yk+2El%>}{z2_s2}`v9 z?e=!-^a4igBKo>^Fk=^<%d)O%(m=<6%gAVpP+O%AThVA>0eI-nzG`N)@g*om!jiPa zW$7`V1b-S&V)-$eMA!yGr5R5P)yfmT4v75xEkQu6BqoAPM)z z)sVDppRpr;J0x7|aIP_BaFJXisoFv%>M>(Ft5c^&Vj+nA#^NQr7#X#33{wMNjPeys z3#8Gfoe677vpkBsgH)ZIOmq!>7~1B(dvS$7!;-NWp*(e5W7-rJ;L|c zz+&2*8_o<}F|F^nPf3rHO)j^N&Wy!C*jWsdY{_&I+>AT@cLHkjak>~#3wpznuBeEt zGs*~Pya>|hsPsx3o&+4j5y{xVSmI;!yM=+jfrM!!>xI@$2<&lijImd z@{XS4+Yp`rY^h(s6#K;$f*Lg60)Z)n7q?;$X9c1*n1H46H8x{J&9?Kz8jiJf_q+>& zV$gCc&VRk}5n&A&6g^T{lU^1NV6nMj?c!NyiK0k?z8=0hJ2+uPLn5&KHR1c+$dJ8g zA4xU|+nE26g~BS_*jEDF{s9_Z)&LI}+Z-7gJi3^wHJd`N)kMfAEzXztu3asd*KI z`<4^#HdHwqnG~Wh!HHCjUBf&q5(&P}yd?{GX)u4)(Esa8_0W)8aS7_gXK!)nTDw7Y$j?|Iu*eT+}T&THx@GEH|5#+s^_3aj7E#tk?ee?8cc2}=h zTG6XD?HydoO(6+4NSM?m91syV-59!s6p3kAdqt~G7wDcsUWnbwyV)@o4FJ2lxu1{e zW@lG7;YI;P$d=F_w%)5b5BJJ0>WQ&zinZ-I+n>$bYTJMufS=P;FEyq6<0TfPCK2|W zc2tmzY-q@O;(Dr4WTHo6epZCS(uZ@4aqS^eA}$xtJi7XxPv5xlvo~&hGc|>P@}`C3 z>a+Vj?gj^F!gv`0M474)9*A+;=l*yTUv?T)6Vk(RchpUsYdY`7Ghq~WTuNKOCLAe^ zZtcsQbzi0hIhTRnI?t(Lm`B#~QKsZ#3~twvAPGj8Q))M8cm!x^H~~8LNeY}%l%1MS zM=VAvQPe1s$1uRsZU`oj`4QCQSDy8)2D|7cn(Gu6-(&`b8Vje3YA5-+KHciH?Apur zsZKl#tV{tx9PHL+2pZLTJ6xqC*Ddo*zC`ID7J8)}KcpmgmYsPWjsepcwv0k}s+xmo zd}sub>6Uv}i4+Ug9SJD&v%;h=adzJ0;MpVEC{+jTh0r&vqOVerlvJ`%R&$kbGHN1D zMD0CJHc<>Qn@BQ($g0!2)}DARj!)xx9%!4b;}!%(m#e8qh6}nBd{L0{{>lf3{Uxa9IqaONFQLBcbaJV8C>!mB7v=t>|I$fE2& z@Z{NYYJD&TbD^T*VRKlmo-XH~JWGGiJYkw)Irj*yp(7R#KTuA;MGNKTV4jok1~P0u zrYo%!HC2Xnu^j@}`}ZsD0{^AXd<%h~7rW^qQ^j}PKj;{g%@FE^&TV&QX%d^W%_WRe zwa-Fv{Cb4V|E)VWQ+cUabR)j2CUammEKs_3Uz!6x?1S){nIe43-}tRumZb1ErLa8r z1Mpd%`+|KtrO03#GUW`kM;nrO=~m04*_4i`)Aw>)r~429!oL<4?FsBMAZy`-NxN~2 zDPY?cstrt8elT7qX!zV6XGal`Y~Zu@tNp9msGtB*1mfPu;&}}q*dmZ79*Sq{0x!qp z3*`*^qIBn%Smu45;N=()E0;?UTX-lQr2c{lysaD0F5xNH{U`t!!~wUEMZkP0fMWzQ zJjbT*g+ubNp=I?h2+dvvkeSXKj@272XZy;$9FT=_P7I?3ZO54x1T-rc;gE2&>(ASW z+!{1?u$>cV*Em(gf<{K6Q?h4vBE-@;F0lzK6PQ{~Z4n--tS!#|Od^(}hvo=n30aqk z;mxx^>y?mog)L%v7CZN@hODau5~nOQO<8(E)-^UR<=p@nTqo9z9m0#!S9Am7*bG_M z+0K+_G2jiy>=cy4;tt=mukVNm8{Q?fDT$6-%HiZ(m#MKR)Oi8(HLz z8FaFUdEGAqmpAtl7fojeM3sx{p3EUG(JKVm%06aTHaUo zx!(SaF1bH2X`hi@Z?lkfp0k{CvY3jUM-%19z2t&>$;=0eh7+9gs&sgW#_i=`uPdY1VX0OiEsl=FfUuMW@Yu`DK+tNTU!CrP4 z({cNgT~}-VH^qz4PBd!p6-}t^ympz!)GYskA;xZIh0i6c*dzlBY!yJLe58Skp{ui5 zWmqw-QQv@;+Sqgmu)o@k%`&&LDNMFhJYoFGx@H$a>)L0#Em!7NyZ?Eu<99mCwrE#G zZd*4n+n!lNTueLU!3yd2Ui%&trSCyaEW0mWyt)+?GF=aBwh2R5 zEH`pJuzS)tPcOLb+h^7`gq>)9l8uE5K^Z8Nvo+z1g{DzKK2AFUwTx*hx8``| zs24-y4mb*aeGn2mFGSVA_1&-Uu?_G_EnI_Dx@OT6LO7s-Ks42sf!d-O9|+CD0kN2-3WB9zRr#LmaaSn<>;2riR)% z>SMVkOAV9KxL$1sF%pXHEcpHAfq{(xO<)2=1DWPP?~o=$m*rDp8EoDOX2nW?m&X5t8C;#H;9lXGl&gYY%I`{(})vM+^>+S zXq=HL_16@=c2%aX&e{k}PAq)~D^7|Jiyp(%m0~zs9?E-a$>(&^ zhVY6gVR3|rhIH6CXm-;D{mL_HvmW!ZGYt7my%)&&1Y>4g_HLm784R{IV??sD$iN6Z z(ZvEGZrl|ckB*DTB4S|?Wqj5?1lxuJ+o|aaO;VM)M8&MhuQ=m2t06_>5udoI}6SC>Z?E~4;fYbNe=JuzpzP+3`uBwsS*Fvp4gP(Ez~-h^eTCAx*t_pfTlLG7yD&%}Yh%ssmL(GT9Z@$s+R_yc)N zf}y%7(Hb6IecC&3IqJLFm(^LV#m6(@XSi#{R(Bl zh=rFx*VZf9qjnX%>IE4)?H2Ze!pE+H+g@-R8*nTLFR3^<{fKXz_>*tO@VJ2Cv6Bps zy<~W_)pmjLQRcXD3mfyKUh_s!xF$4=}cx@=}I3=+JQ`JWS#4wYq}aAP9Xx;hpM0r7X@iimnBM%Q_@kkYM$h)x&i*Kj`;@9kI*9RdQ^-c#Q|sRta>n z#o#47o>t$GV^PtD{3L|HaTF}mwgP1AL0nAR@9`($sIwpvKvDW0)WotuwQN`5Hm3EX z@CIEm&DT_{_!QuRjJWZ|IDnoF&-g6QuPHAstQUPBY1sC7(|x1{3DI#zGgpmf!eRshOCt%b z#t|Al;BEx&YapgNALc_oSuc|Y9!79+A>bm1TMXQ`k}?1hG*ua&6>xb_I*GI(!EE&5 zx~_@H3t)=Lxob)r7N?#1F9W0r$jgcfhzn~_o}gvuBD8^SogSTFqb8QAFLum3eWv?C zmjk+3#jLp|C-MMwi_J=1tg$0XZ_w31W$F_sj1`6mIg@lT&0U^B@tZMaE~@3xZf7en z4yjLCFWn8*qh<@Ma`ldAzENL8dkd%D>yW?^CyXG#lxtpM$u+c=TFG-W=mEwZHCtg- zqq*jI!78a-$@$S-b6(u)xe*4l_1e6pvq_hf)YhcbRT$=HsRa}a%`U`X9tS^5Zh1#y z@A9)`tC-;Tuqvd4sh`Qul9$`>tVB)K9wf9IgDEeFzeA226||Ke6-GD&n)`KfSm$O(eJ!Ym=c&o20-o)p3c0UkGh}Vf?((%<2w4}{ zx}AT8L*-(~x@gK@JZ6(+IRg^1wut-5eJudA!(3H2E)%nqR|q{^4_Q|@k~Gi4p|Tb# zygF0P=UJ#>8zF0(^-s!TO^e^^9CnP_WUk{&vc)+r_tRFxaK~&0YxN6}MmLi>KOKB6J@d89=&-y!IzOU! za^8s|#r8bb!?*38R6f$crO?$}tK0~U zO1aIIK8N5^a0O^nr)huJf-68pz%Uwx z3Y*>}77TGQ?T{P2gDW7Y3ZN)`4{BoBh3E>%b_XuGg#!I3S};zQ2VJ?;-cuc*D+$lu z9y2s7j46HnJ?)O#XDY>9n_SW=;e0@Cu7qi)vTA0V)u5w3A%_jx*GB19labnpVPo~44@*$dT?|$j%FRHSh4|4re*fsAid-d^95MKI=jP6rL{Fw-g~y4 z$y1|$sqlHyn3NYLx&p3ad$CR5nryj7c|NqA*UlEEU7GZUYOiS5(K8tk_B)xXo;N_; ziw#n4oMmT_0X*gkU%Zv4b=thI!@`US>o5?Mz6UY!`*0KsV;pVC(y4o8&EjSk{v$Sw*IQ$#O=BVBThvNO7#Molxs=j(zCVYKsg(=kK(YupuZ zf$H}|DK;?}x&%5y7C{PusIJN{n#LP#qnU~}VZsWGV?LJJXSryWc6!gar*Ax@etk5G0e&3ysL zW>cd{Z8o*l5gQYG5z@4O&4w&C7HG+7#EEF)+UTmFCbTOojp8mxF&8a6CeBH9smnZ? zpSUmrh29A&z8;^oa2QIVTo4EthW?Zear(LZtn$O7g{nZ zR@YfL8EgKvYoBGWHb!380U4mx~rgfWY^Eu_riP2uxxS8guTssVV7*{28?8zn?`q5(vI z9Pk-;M7RfJ%AKU)AlR|KT#S9$!<=sGPcx?r@&fKY;_wMamNM$GaX>?i$BwwOk+f^| z^bB4WKgAVmu%>4?cQ-(FH5M*|D<`hW%_EN#M|1R*1**6(x)q_oTBQ~C2u9KH?8aZS z@{fUkDSo(zz2Dsfcr-BFPq6nl5gV+~#*Oya`#D*PerTyUp2>LvKv_@; z{mP8rGkgC;$G}A|2ywB!HWZv_@4w^)83x(=twyu=_oBW3e3t{eXQHitjRU(|?g=2G zO0Huyk9<&flR8D*n7p}y)lVLzkc^Nch5RVQ`tw@tvCpqGiHNo)0x2^p)T(#|XoBu4 zvO=wE9Wz!jo_FPhChLk@<^Zpotk+ixS<}I)*4@}3liZHk%nun12f%I84Z7zc7o2k` zCpHR~#iAQCrIF>`9ovDc)?Lm!reKk}%XP>649L36R2pm>$edt6CUKr^w$VxpU zI3e^GM5R<45X>w#Af?gO3iGq>;iQh3=R2UR?m>!3$T3#dO&Jkm@?=gOm6W#)7TVmw ze1^08#u~5Hj*(W}jL-kxjXs=VIdX>WR`LSEAMxL-yKFgQd)X`BjxMLIEdVsFw{BW? zDfms~!645lXV#`NgwWI5Tq?KY_4N_O^U7HO#dR$TwG(n;{e$>lCT=-(GTNqYyz&g(*L!AHE;ZPiH>WBNrhXEN zpq`zI6}Pw9i@fS$$VXV{;R|smqb(1I>W(O&WBais+cQi0Gb+>TDfmfr&d7mn@9RLOf^5 zGy-B%_LqcZ`+Z%QIPZJAj>KPDy>Em57TQ67$bwreumXTmR{%Zh%2w#gCS3`4e_@7> zP15{YEbe3%Kjmg<=AtVn>IzpO-{LC~@5&M+lL37F*UHgBNj6U4c*GIQ_G`+u?a`I zxZO^y0v!q{xL6lBtO6G)uxwWy4sMaXayg?)$=N0+Lj_webn5o~b2Kd)3IuW}5s2ir z$Y+V+fO4i%#u{IUa`u;X;cW_wayb1Ul_M<;7vDrsG-tvBPSI*%xaMr=3FsBRwTqIW zhY%PYFr39v@l21iy4acx=RpEd*M8IIHD-_z>r2&ji`V7Ds_~Jy>JQBVO;iy5=4^NY zILpw8p``vJ{m4U9*wo9D16WH=I89){_I-OzaS&@8q$l; z*8jEU(AHE^XxL&ZDaI59#|P*%I9`h5rP*ZTMc-0gK;h3;7aKRNE`_0nx_qu37@2E6 zGvjzI4-d%Q0Ue+z1WUE`JX0T_)4}Hfr#YC@V6p^fGM~M`j1Vw0+ zMlBHKs9Vm_UIBLSN$q-%mQmX>5RqQO{`f)l;b4qxWNk@{u91vS;UjsV7=H!3 zrs1x26nbWxnSFf2MHVuznA+fXFN$)cT{W3xR#Q|vsI=CBz{xE&)%8q!r9jeKfL}^g ztPItn6%~+=b(=GBKkL!@WFU5Dt`u(?wyMq}L&U?{+A;1UV$U=BSnpxppP7D;$3qW4 zL^Eq&X>n;oi!Gql@*@x3Tf7AC&zkOuHAgIQ1HmZ);J zT7H;6-O$g6^!$kRQdy5YL>CWJY(~XqvSK`kVq{q{)y8qO5A&z4jptB|EGwqdc&Alt zIxEI=C`OhQX`xQD2C}MfxvSpMwS)Rsuc6s!~Cg>@f?bg zWyRPL%g|5^eKgg^b0|iZ6$9|8YNZFkUgtx zs6?w7J(`VL*-g?w3_+X;F+2yvkR`-44pZ#eDWxF>@$8h+Kq-0-l+v*KNYuBRQc7cv z+MbLqMidmH8h2fM(*+1W;5N7QSXK?j#Cw2Nb_Ng zo;qu?c-^5P0bPV(bYFL9&@7JgN!zv`JJXW)7z;+(zPI35YRz!M4Euh0hMrhy@U6h= zpXh%`tc40%l=3>d)*dgEfVY&5{)g8o)8I3)8WA>5I%@-Ptf?w)4PWf_pYX!JB;eGw z(f`VVMye)6+N>I{@g`WKedjzAjoOE;`A*rKXQer4&9%)fes2NjgLY5*=I7YQ-UKPi z#UI|}9*}?W7=0VyL1*h>lkIoN1-{0c{#j*EALXD{YT>JlS2pe43dOo?7M=f z_hiv*M~_9+2Hsv zf6~mU`j7m*Mx$U9IhwRAzQ=~0KnQ|LZ1oZAfeNf*5J!OU+&=3nef7B`D{!;_ zdm2l>n z4X}=hPXH@DP{tpR0z7pyfTt$|JZ%7DP!hoOMF3Cd09)2BfJsdNPdUK+NL2A-08_~r zz^WF20rtQ?W=;kycB~rMsXc(bGcW?t-iLkWiN9$w8*f-4UzOV*F)-tl{Px8$4WuXZ zS?@&@R0@CiI24mN$G%lTTDV|EU+^qN`~S#_%{Nwm_zVB~-G6%NM}POy>E80lN1&sB zQKcHazt?O==EZDm`DoD^-De_~Ol#;!llbX#OyWxXsoDS2GZVgTgl`+w#?MkzA2zCc z3>nqcpRp7=(f>tn_doRx4Mbec{-3Q=;k-XT?axA7e_gDK38m*B$)4Y#=iWbPj z4%oC8GKc!Zd}vk|eo=it*#CE`+F3gMzWU%VD0#O3=Sl|0l2QV@sD8n7c$zy=UD8Yc zw^itN*ykU3B|4xb&VaJnTMP(p_J7IHf2P>0Z_eoauMPUbbfa0c+MOxbNVEFDuc%Yq z(AS2^uj-FK>OFM;8gsDoX7#7m$$hCL!l_w(&Ju4;iEy=Mb_)aJ;u){D^?ikb>TAmB~f` zmf$eG%}8^vQvFbB$C{8Hvumg(55g}N%~oVg**aNM8bMZ6FA3U5QGMpe>6tB-rG2o{ ztgbr$S+1JSUPxL#(f?CnNj#=NoH>Ubx(=*58?EEw01gw(?Q`}m^grumuC3ji)HkFz>>_p3=x+Yu)0ZZHh}L)W z5BFk7Xoffca4&}Rteos~dvx_1o0C0Qk2V&YB2Xt(sMSiL)ee3P+v-@@v4fT*dkj8VAVqWTs=VnyUjde7y^_g1=DacD* zP`YGYPNv>ej+ed4$y}An@v>LBPF{|ey~=4Joa(bBb;QtOuMi>=Bp@=Bl&ui%P~(yu zM+N}1oMm7G%6X}aeU%l8Go}i8`I;+i<`wdiS4h?bfX9hvvDbS?F+x2~F;G;iZG@64 z5jqln|AwNY*L%~*TyI24BmrsKk~ZI)&1Lgl#&tzYPesv3)bV>QRTq1^%)|{=?I@s>Ic&i)R2Rq9Qg@gJPG`Mh@9Y1b8n!%HF-c*eA;Dw)!lc=Jd86Uq)7V;Drs%vi zuA-o|rALU3RBN&A*cpzTCz}IbW5RsZu8k-$F_qe$Sjl|V8rboRf#$#>C;YWF8CwsO zO*3H2?9~5VgGCtzi!ciWT2YZ144wplm4Xm@E|`EmroD$pMmpo_)bVv=>~FNWW|$tf zd^&;t2wLL-x6NyI6**}1T<((+mpdb0!$mQ{1rdEVv!mv21(pAg=IZ&Z2BSD`eHCYo z>t?vl*W~J15Z%@j=06Ka4EQtB5PF8~fIk+^34h8kM~v_%w^EHijHEgKk^!L>^1y;@ zP%QN%R~e~gYcE%sD2;&)YbF`o*hTkQx7)5?)Mh2 zpdx0)F@E&5mYsUi0`#aoIT3V31h1h!;`xu0PY@7)A%!t2P*^RMIz_NN6svHUddsU-v-g~~_z zBWJrs1OUW`*FjrDR#hxUR;`d2*>3M3Ake1uM!(S_^8zTIMD7O%ZHD%W26;TBE~a9i zYB#5%Df>#!^=N@YHn2YQW$T_sX+ulz?`aGeF)_HR{SYH0E~BTZ;&>~O3dUrHe>h#e zL?`)ASAWrX6@*YIk@1=tw83+6+!Ms&`j$egPAPW2Tj+vX#AFU#(ds>o+mNw*>GgN3 zA@%EPqHg}8@#^`hYCkn;%!S{qhQ8Hc6m(BxpVOv3UGU;{!)!ur1`kPqfckVoE(YfIl&pHVKz&J5I47=w%O$y zX_3N_nt8mahiGxxdpN-?-HZG%x zuF?<(4U;ue)Nl$v<7xA_LDv(vvd+uZVE-sT~>jyvZ|T-JMpD5b!q1hqlXywoSHXah%3TmOy|< z;jgNuVMvM}NOGa(>XfEV&0>m+af!`oE_cKz1A(<9E37S=KxHxU01{d*$*tnPdvTp@uVJgWIa%@EUF zcy0M>Y1T?|6C)96tv-fAxh0Wh^kuKxSg&l{5o3moVAT>EcIp=4*J_xkQ?!vNc&F3oU&nQEd)4v$fSdoQ}z0}R?bn)nL zf=O7bxS+oW%vhJzLq9zLFbo2mx>p3S2x&Xb&g*+<^y8EiDGFr$)zDN>;9V{?B^SnN z$`GKK(1oJW#N6NfW@!1hey91W`I$NRVY7PDLV-BG^l`vK>_F)+Z!|S_vJuWOjWx8P z0ytn@LB|-xSOu+60eqz6+LvsNB;pe>MkqC3O@uUKr^aGK+6bBI3yN!Y`4grP)6yyT3l#PI(Fg_y;<5Ol#8t+5gx zwGxZ584HeWR)1uv`@?reo+IBGaLlo4O)k!=Y-@sUh8Fi9J$WoqqU)7^@MBU}()g z{ID2dqjww7P=8p@SnG&aD(L;;i#t=?syBUl`cw-0%nWh)xJ`Nn8?7vuy?CT*y=924 zg`jpO;uI)oSLR*lFyGuVFooMq(^DG0*<>&h+$+{!BC0_dBIOgp*RcB}cS3U9R=M$n z86ak!u;?sxqr~)s&%$^Nv}uB%VuA;QI$Zv^vB|N*kz7v*Cvd)>P;uu4?g#LsJ%N_pq)i@SAP0>Yym7C?<1Xu z9Iq-r4O8p&(1B*y7yhTmA8YhK?qghCw0PXZ)n_dA6P{WwR=1=2yl#Fv;H_D5L`xfm zW;lD|TlmZQgw5}jX-6mk^Y_-(Tlsr%waFbNiTGsP3x?_x5c>YRD zsmC_f*VkXxKm>|{!w7T@p5=V}u}QEyoD@JBcr^bPP^>i*A%O>KIAZwRh?dsdz z-fJQV!-rfdZR0&fWIP4e1Ps{5I@l*Y;yYw$kX9jqZhUyIdh3Z{x11C7Y^@?(LCNvI z*6|W8K$=nSwG5y{Ju-U{PR8K^i?1c{XjZ!bm&@7L&QGz!o}@NE$mx#Nj#0Agof!5d zjYs&rNdQUYIw#6$ycH(~LV76Uu=>|gPGeynDdTe5%S1WdL#4~>aXIZ}qMXKHJyOQy zw3mr;x>q5mv;Mf8_A*gU_rQpiVg5=Y*HA?{jU|c_94erJaRDJYjh-es{SC&6!2E*9 zY`I(zT`UhcKX?F{Gd1v&d=E?Rd`f&_WJ+i$|3OO`SLoiAmrH8iNApxpHd(GdV=15X z2_tF>DdY7$HS*;Gj0X+1L@*awLpnywKAhF80g11jzlE8`6j`zr*lRt^K4J#IFU+6jFhgE7k)0A-lyenfzlH4MGB1Hah{y z_Ic#lE*)BAw_eYTRklwd&vpUPA-ny0=C!hY_IS3-h-tDrug6TUY@axu?P6kv?5Wq! zOJftisNr%+p)s0%{k;6=i($g}*Dfr$^9#lV3+7-Lu%`9+Us_o2sj{*Z`}T&|-E-Ak z@1wLGSK5B9rhz8=tR+BiJ=XV#hp=e*;7@6UqIl3kgkwS2^*onKY}y!x5>>%}7e_|5 zErx2}%%*R)M!soPxXs4CX@zgP>6`75Z&ENW(WH@Vgo<%YRyLg|&{)|tiG_kC zX~GN^!wl?(S*IB|$G@T_0}bdWy#BSmYP9KQ6Rhcild|7!QccHQY9-Do2x?|^?aK`@ z=e~D+evKj;zz}PidYd8@B;&9+v+;A5M9A&cQ+``Ph24;nZZ3pdtT6VogZ?#JW zSUNRebMw8`et2#2I@eoWu3stDQ&KsaM6&T)WvxueY7Um?=;zVNS$y4>2$szHsNwXV zu3Nt>^N3tCC5d8yMxY0brGJbuv5T#?} zi7l_05*mrY*l*hw@ULia;0cr=vr$>7-N7t+08~fY`iB*$cop(MT#qk~Zul3>RejOR zzX;_Dm0Jnr(AHFLaY8xbWMx0|`k3@8w>+U7QbGm@FNfBqa{USA*cd;v+7IQ#%rTE) zWOG1Xd&mPHGF=%T)rj(3&OBircxK{ksnZZ6CjE#wpZ?$+nQ|?=T!i;r{4p_H8 zvc<(?6>zC(cNGfsbB*mQEp)@3MO(7p;Q@FKk$nP8XCj#QDi~YwL&*D3(lK|f$%d-2 z489?L<8j&HHgY+ZmUVXuQH=PWw2ZjBc&QHM!=zWvcoY*s3j6#C=f{$cy|YHWDV7oD zI3Z2ecD2PRJV#_>!s?u+!zlUbIHYq%kU<3f*knJ2P9jhoMKliMid`%E9~YLK56PvZ zP{{hNO(a1U|J7kZlon_5PJRxbq@Tt@SE1=Oxmy%u@lRDN3`0od^_g{hmCq0xz5F}2 zuP|LRAy?9zl}q!Bd=LNm1OSLgQGJqYZ*G z`@g8x0gP(zZj~MkV#jMZ+3VBbHE0ya&A;f5RLG*cd!G_*ZD+I@!)GnZVp90*k6k7=}V|&^LK#e2XSUV35eGpPd+rP>v$ zArZ17+HBuvhBgH$SY=^c!bW}VHVyS&iuI1-TP*gb{dsTvE)DT>>5qD|73sCSnVamU z6S;5GM=YMn4)=~Td;M|E>^6M6_oY^Idh8@C+HO6}*-{O3IQfUbz9cknc&-N1Elw&b zJJ6PlNK-N*DJT*7(I$Ud#;56UV1N!xZ9P~PuSTYdB8!K~lUCj;j_W^48^4}5<|YGH z;@8uOxgluHE7xHvF**Vz4?@HtDW4;%MwgDMr=t3?qw^5q9DFH9zyA56b2^`R4plH-1dlv)HexP zEea-38j73&qMlM5FW9{ed~Ea{!yNGsfGQ8`w8dXWU2{!w=1Hr(V(YF!^{)44so*mS zfh2xEn3w4NceZ`S(Xamc05og>v~Md70JM=gckvM>XD=An9I&x~^o`?r5Jcf#?bg(VquLLb&i-eN1n0LmWvr`|^t;Up}3G`T1s1;GVwA;HUtpU4xV% z%XCFlD>ZLFGR;V5GtfJI`&@I)soPbyfD7Qg8!}MPS;9pL0huhcN>J6atagSHOOE>Uh4I*PA4LE}o@3}5bFkQobbRL#?b5@1{h677Q zl>{?Q6(GgG`J%6oF-AFqXexW|WY7V29JWpkk+x7U;GODY9}WX9##DXqiEO~F!ho0j z`L(8TSxVBW@_bEy_1b<+jH=hIKDr-$&IU-^r~gB{Xw|eK^&umUIQRUQPuH*|=178M z*e5c9WH>PlMHLlx3M;)I!#2f~t;#f2nI;_w$t0pF{EfRCpAz`^X=#c5EF?TtCx9Ii zK2|62_R;tz4Q6$d2G`n2@wc&(y67RzT1BPCApi?$U_`^l3JFFmdrIE(vBLwSXH#AW`?+%s_27Sh?SL#7MRA}iL9Bx(ZH^l8pE(BWkBUe zQuCu!&N`s6(ss-kA9ZJZ_e!Wg`vVSHLdQ0V>j&DZxAEfJBdy>6$zCfq& zEr%#)TX4Q-rPGgEhyVJ}sSST5+MIwjE?+azLdRbvxnJGIYgk>Do+ZKMQgTKf6wS0d2S2=mOwRq6l-X{L#4(RjF-2a zLVU^?r-M(_G|%^m8)j5whB#3f%^?rGj*O`=(~QcnWN5<4l$5w(%lSmB`b?yk3-lLj$q6QYXPt3eGG~H+K+VyAEs#WV>t*X+h9=44*ubDVl7J;@R z<@&FhLm9ZzXst8bmj{9)8Tqe+Bf@AacuELuRux49Vp5B8RH|-q&2O4mhwYNJW)%Ie1j%SiFi&NOv9<&v4uQvW zNt((k>L?6)jJhj=$){@1U1--wVuc{B^Q7AIWzD)cM2YRx$1&Yf8v)Mhl@(?qX+Ju` zR?@7NXU&luA0fDbbj7xO$^+XoJhE`nQERr-NaQfm1~l6krnwI@5Es!f5K9UrKmtKz za`wNbK0h@iSP6I0n#g1*Eu_6ujv*`TK1*0^_c3IxBaR{G&(9a{UonR08Wt1E+6@pf zE_&lh%9;iY*cc(8WJZ;98FHweJBKken5a>6p9ErQsu_smrrNuz1#U zbSpCunP%Hx&`_vQbxQ!5aakKes5EyVRN{~uwotD^G@gr!3l%+S}*{2lJRb-;W!(j5vZ@ZIk_vf z{pHhn-`_uJ8`MYL;#-^wp*FjI0!feE;X}FpxGp->^ed`+@MY6KsA+!_KN^wgR24G# zQ75a4aPE#3vN899I2bl3ACqC=xx>jkay#sA0*oCs!poh_VGmY{en7^%nz}$t*Udh{ zc3c|OcQSW(Dnq!}TF#Q5Wxt#3I3PSbFi!bSd~Vt-_Jf^x&`&bd(wD$;%z)hK>Gc6S zA9L*VO6>F^cBZF~kJ!luj+qB)m}!9-RYNm%tc0winSo_?3bMvIraa&T=nd&J@j#V; zm1#dsCE_6>z!0SSTk_s)EA98Dx;#2+riB{CKRGJma3UKFOS(}`5kj+h{|0u)0W9~Y zaSFyvJSj&2y&@h*Fg<--K+3rmYh?6dy*!R>31u&JHT+CCr2;5^oRC?@ZgcXJ)H6Ej z^ki9z;NaAB$wrjSgL-Q(^VX8#(Tw^!j%}HqJ_fKhCqJq|Eq2Qg-_8x3+#R3Uqi)08 z$MWgZ@}q_dvs}mDqcfPx!T%6Arqdec{IrHSI}#o+f2N4|P3aw(BH}lt`!b zKQlj@rPIx6or+_8m@l)InxqX})t3~Ct9$<~a9=j#+V=Ggw2$B8l7fJ~;zRbOQ+^Ru z%$-5iJ^M$Ir_paVT|8s4c*g6sOe=I|+h)_W33;wNgAMUV6UiONv8?nypF_p|%xIKe z6?ga}9n(mM`5pRp+!-^^5xZUd^&&~U=`Q_RvQn-!N%hjjmPmb&zL?*a}8={5X)1O z)b8#kajte~($lzQ-VaTBnv~IFeA3Fz(ok6^fG<}4;9Rf(I04BpkP?66R5AUGP`Vu8 zBLLkt53F6a_>OU5Ow1D`d7H(3bn$q9M2;Y+*`{-J^^TxkU%k=I#tD(Y6SmlFrt-~x=9A6+MvYhQ^%`N*B5UvZv_Z6&D!DE< z8`U{9+(j&|H+^*IgLjD}_OdfWZD@fq^pwZ~M@MseIoO9cy(sAOi>lYb_Vo&DIYGa$ zmgB?cqwAzNM#i^fad^1gHIT6=I6t=Rs+aXC;D>)vc_e=$@#`!YMvSev)*o#|uR$f4 z=9Xiv9Y)?M%m~dVYnp9NbnuflK}dXX=dO{V21?@`9EO>`PZs=f0Y{V|&|x;xUbi#7$)H1@$u>9#;uu6}c(2E&|hNZ%#hIXi+MNcxh>HYDxPOM1{oqt< zqTL1cXx4@KY!K!Hlim{M$7%QZToC5HQkd_p;8Xj11<@Jo590YZML7t(MB0nQ`J;C1 zk|_jGb~vK%I2zUweO<))aXRz`LLIO3TCX!GnD2J%28n*0;^Hf4G!uH2MBmeNiGCdu zThr~@rb~9H|0r=6&6P6{Lr2ka51~ZbQM_UjoJn}a+@>TczWQe$`nC3%Z27Vk3zeGH zS5$!dSLCwlF#$eD`BHWt#iGwT>T)^NEFOWelyY--QxbJk3V6m10FT?cH>H5LPU`?= zK?bmRmt9=c9F)w5afPk=SWinym)`_RI+^mClI)NO&Gyz3k0<2oL%9>gSJsz&g?gr? zT{?e(gurUaUzY4dLLx^^CFb8UoFGh#*5ybUEfvsGJy=MC~1y};#Mt#2+xkDlpx z;d?8&M?IC$3o=AvM}~=djjS_4g0IyC2@Ggl)?pBps=v6C9h@`-1~-p@rQ-Pp+AS_t zs`_u$C{q6|`rQMGj%oONoJbRq)#l_^ok&I3T=E5C10X5W7MX5nmO!DtIDt@uD-T^D%(Q#uFVQ!bKU+C z+rhP=H5%gaFwfA~#-azX;oK8~OW^ET#HB<2j_c$ZO zKiRA;C$UW~Q*azvYiL%3{HVa12I7E6l^oDHpXAAG#ra&bvia_|ZR{ian%c&`(0Zk9+}5biwSNX}bFBv?2XNz#{H<#M;K*@jCZ< zok839&9Q0tlxrKG+yC?L?5wG6#IOGh+QwdUPyByV+lYO8;@So)QBSG1LH(v}++?#j zoV+c1;tI<_*I+ko0C1x2)^6e zhN({1u0+kX4xI7Gt^_gYdiP2miEdhH9J{TGl1J`l`>^!r&B-;YYL&Zn7um<$t-C^t zb$_db-sa>gW4F;7d*TjPdNVwo;Gmw)q5KlPz6CO?WxRwQz0$LlmmJ&5D=1I8}9m2p-&4(pCrW}534QWGlQ>#<|L zSH^Fp?-djG@%dh58;|$+Kg`&is5xIF=o37c6}&Yspp;6a{_!&dSNEkNJ&FETc2_xO zqynw!e>DY3;6(@f1nAdt9Xk_Tvua`&pJe|l!4OZj|J7LEz4ZS{^1lM22{Nt_iR!uL z^c!tXH=K#S$>#K!Y7VB3-22)?YoB)WpB@Ce7wak-YUP-go{ou=DXwC`yC_=LgsgHu zu6R_<|0-|9zcl}=S%D8!Y!ukdjyT`Vh}VGq=zz8GOS5&%wmbv30;lmgDPNoEtS>y> zdo%aK@4-BbBNJWX#V%t$`K+B3F?Zu~&2w@!9u4^icFD8xymC?3{9#bR^Nb2`9>gQ{ zb@c%jqpA#=L!Sjw!D9wjl`Ow2E05Lc?E|TK{}nwL0n58Gz_JJMgvpEZ2(AK3&B~1- z{X~w5{CM+D9GxFuc_;8%BsmLL;GtT$Dh((io1Z{&1wwZhU5sw0XC=-!ti;AFFL5Mt z^XZY>Xwj@(ca@tqB5|nMGn%jjzD|Bs<2c}Hb#Oof>wldPQ6W*jt+)iE5n~JB zU3dP8`tgCS3qb)P44`s=sUrr7{5xbj=$g0SF-1fhZ*{U^-gU2xXk@*SO9+$*7g@L$ zW1YlA8XPjkM9bW=Qe; z!E+pkJ}hk>45NlW$Ey5;I6-Pi(0Fz$6j<;_SQ+TieI1gho--Nw2a*VWZv%smtJ1-n z&!9Nk>UE$9aX)$qY1gk90)V6fAR0Q{8pIfM)jIxl`=@Fh=P>}-N4Uco#v)44YzCKe z$vI9wXH2no!B83qFn-Kv>-C)6=Y?$ce8*Ug85Zhr-3dG`J3!)9jNOOCT@qs+?(Le?e zhx3>ka}9iVomeG&SHxg(M`FiBCu!3VY`N>7O;5WC%moiU3ucB?`m+~|Vd2z6_6UU2 z&3L4j7k=5Q^ZkfCh2xcGyr~lP14+CW{0lY)do(^V3TvC%BPGF*)NiaK` z`0gt1uI}|QM75Re+4CM~nQHx;<2;H-f7b#nIYO@ZBSjx-#-$)YXSL`EAh57WKg>R1 zroq$t^2in`aue#jzp8Wpk=F?~olxigs?Lucd7a3#33cwR>b&j9>qIG-Q0ML^R40o8 zDV(tQV+SYk7K{=#C^|NW1DSNpj>hhR50qmU3i#L!CXJmKWeUHYFp99O2|c;Bs{L_b z2R=HX&OJ}4PL$Ysoe>K+l~{Nja3aVJ^3B?5 zxvixCe^+9px-A`^&?uH~WUz{v!9Og+|49MufJ<8t=rzB$m-jLvf2<2A_;j zeAX+`aM!?iTX!um1j^(;2H+$?32Zn2o?x4s0NXG87k%OU1Yzh7Wec#GJf!HgR&-Lg z#)@8FFDkJ|(QjD1%-~S1?y47+bff53t>~myzi9xo2}1xc+mJdkW!S0cXRPSVgjUxs zDp^I*-?pN4G)YQn2tRCJM6|TJUoYhlGA+e2mFr&16_8oaC1qX>TyGhUtXq;k6n(c9 z?H^IMBxET1b}QPQP&7m|O+cn(2}S?Ousx~hn;o9jMJZQdWNnm7Y|y~{*1+@x*dDYm z<`+maD-DWAYKe)!r9#aP>UUYnt zCrX$&v@|TJ<9Ci5_&rIY)vQbx_u_6~GcPA3=tO8cwT8V$?5@@E78!ny1}>d+nCa+5 zs`Pz{xMz`!a&0u=()!9!G{C8eM>Abx_Z9wKPr}%R68QHp=p5IW%{q$Om zwT4Bt0~gK7RuR@v*G#x5ki#e=Zez1o;&BC% z^}xHQGSv|d(N{<3%JVikq#+Oy4N)tXV@&KEskttyn%KFl-Z`vibq-jn&SjxX zd)YY+ygDbM<~`gU_;4t78YyOAe-+ zDaP}|l$VP^4nW9kXaj&2?K8VL;MT)N&2Al0oknH)Q71vSYB!-v2TLn5;RJRLCzc=F5z4Mw-()*bQW%|D{Rx4uZGEd=CaVjfU7f;V_vGwA_;$boT zc)aDS8!cndnlxP%G5)IqIyH-i&1_3?v<@7FH*8Ll;tia?SsZsZe&I&mUM$|piFG*c zjXhYCCV+GdsqQmBwmQkAf1BFWoo6K?Bn0s8`XQw>+}+NO$^&5O1RZbU*9fqh>z{DVv9XTLYG|K`^G zFMQXLww#`<`OK1n&RXVVFq#Q7tECM%J*k!_0{6=}E;%;Hs24P3ubfJq@%k(A^`)rp zQ^jvG5p|7=Y7=wpl}Pe zBFH6JS^E6XQl^zS(1I7g-4P`1T@DnBrg8)&i>{7Qb6WQyIovjj=~_wK!*JLod$p3f zl>4yzSr~w<)5C{j}{GS)rrG3*DE;6_;&PzJmhN9U8t3@2gOb!UmZY5ATyk z5-&=cD$as>RO=KAk_2-=d#y-&3CX=W^=Y2esE^$jMt!>fn@4I=m5?ds^D62{m=9SRd-~`Ns6qdTwntNCBw9!;wf<%aoYQFSs>L61Ab? za%l1*vweDTJD_SdHy5{$G~;b$cFJcA8I~Rb;Y&AhV@jfrpr0AJbkiSPx}#Xyee0!X z>FNQSXXwo~y=r3=3UFa{_EIu+88PdJ4dP=TgaL?OAxn{*I!gfkn7~$z@X}q}?Z~88 zbJ*iBgJKRw(<*w4RJz3Z0`_ftff6`x0A;|lbStdDpkl3?Y)f|_OrSQN|2=g!wx6DC zu(zXk77ytS&dIm-&hj&kTN0+LgyR`0&F8!uj(hh>%>iK7tud|1z1|Lb#~?O-EKfmX zKn4>_!i^0A+H84#xmQ`3r!OxRORRxg!gK#baE~uCy97vO=naU}SdZ0kyuH!IeO3c| zQFIC5SQf_#oi+@4fweJ2;DycqfR%hoTC`&&pIRF$3L%<`Q8|nbxRFQ2{D25+U6f~1 z3j#rybMrL{6gL@i+=p(i<~k!uq*Sv$j}%6Th>eYeBV1Kfol0~QqfistXbOy>or)FK zKlcVv|zL$yVNF>a?Bnquo!9qC)biVCSkGfHd#5t z;{E!KRt}jJc0?907S_)t06Y!LO3t9JOh^=mV)-K~9WJZFo6!v^w=cU-LV2!PmB&+J z9-Q&iDjA5#frqN4YQe{1OUr|Z-X!ZNk#z(LP=UMhGMRmZd>5^lTHMO`OoqByH0sC< zL2l=rV1}US(k90iNe9cMSfY3Vu$e(p#PYV?X`iRC_Wr5d77*K9X-v4$7hGha3|g9s zorPB;76VlGg-PJjWRSM%hJ13So!JLq5hUshh8Kz)R^$ue(lW2|;f;M%I>57xh(MyKhFFc^q~Um|(r z@EfHI1xmh4k?EBDU_-8UVGk*dCDFSO z?WA|XLU9VhY}Wcsq8M^k%+8zc>!*fEa=y-T&4gTENNna}tY%sOX>5lRGS`IyX#)q6 z3oW}gUV0W-WWm=35VaDqcH&=i!AwXH3uy$z>Vu}Rp%WLX?th3ksyOY+_)ZNS8En#f z+JA3z5(3a4bdpF$s~bH_>4F&db+lEHI3Mn50hv_AL=xM zCt?MSz|~gM$c<^H+czdGCxC$Cn5KSB01F@8`9LT7!J^O8t-UwjVAQ>Vy-wg-9o^dd z37a+)Sm)#-e}TSb_H_xqYZ?iPiJSx?#N2K>ZI{(0RC6FX2d{u=rY%R%Olm&3s2N;; z2b?2n2E{RXXMwKMe4S5$k5OkqZa;Vg{-wx4#KVLue9tzYI&xApSKvySR3=QRxCGOG zXqF40DxT8xnWmN{@DWILDOwXZb}3S@%FQ2XO}FNYk!B!z3(g2?;lOMxU8ws!AXfiLU%Z>u;Q&-N4D+omP9L zuUGGlM5EO*FBL8{Q|Hg*FblJ#k==}sOYC+fu`zqXh_&Y_D7@7?wN!Wb<>cRmPn#`# z_@$1#H5=T}m}$mOWn-T=l!VsIVty)Hd$``3&Aq3xwXfA%v$JuY%GSPAZ_QZnQ`y?r z>#bELuFa2JtJF*nEL<@US-6_`X5q3-%VRXi*$u)Q#-~}hY>wisW{}Sy(pu)QJc4O* z>&uasJLU1s=9R_h^V~L0=SH_;N7Z}~(IAEt;TtgRoLvUC@#qdCzX|IQjH^F;oIik#=NS_!j+61 zO~-96bv2r8EX_rMSSqnU=4+yL$v(oZKtxFJBuR&evRxl)_Np}QnvsA>__eQm;0tCX z*kzB*DeflxJ$az|KT)%Wo8z!I>q1EOq6M?8HXF65p>Q!|M2h@1FPaZWi@($9($7(L_zXOF-1f3LL zaf| (R4rQrANmXzC{*p|dBiNFVTWpY-p!Fr3KwzWzY25>g zKFHdtE#-OEO#0Iaj1pS373|O#{2p9`&P2|$mmo3tDVG08&BZ(0_k5H$1rYq9Qg2&! zR~XaQ?ivNo7K3y$x@K?d^R68Ax1PT1hWX8jado*9;V!u3w{E&}t88g*{dz39oc*y| zpS$Y@BvF+!jXBqcocI6x%PH6Ow}(!;d|9Rb)rwNujLZJ7O)HWyc$GX_kqlpEXV=#5 zF2VB1oa$e%=SMr2FAGMVzmqBTdAn$>cLS%IJxvbj3Q9D8cJs2VFqXxnB` zgvzvT)}CJrK~tgVp%K)JIgbcIeJiyJK|0)S0)l2@8;6Uc)jgh76_Zdmrw^-8r>#yP zh%@%qprE57NQb1Lqhrn^LeM%ZwF*JHm~aAuo~Gm{L_x=?hE-@d)|$(EtMQ5RUI;pR zO#~euiXNJRnEFPhTaO4q8?4kS1Zl741Oz=jw(~*7=h0(0oAj~VDm7?6X<(uLm@#KPAe~kkM zUT1y?7R|-)T4aXfinU6v@o3i#b6>G|D8VS=p^8bldm<0Lqh2podt2_IiVm)py7N?Y4cS>#uG><73Ppn#qK>6_|tX=IaSYf;XLO~KdBiLTbE?VI{Gy&Q> zYhg}pQak`3ph_2u=SQd*`6-bEuxR9)MA}6`d0>BCPy%srz;IWtbVD8wkEPI1v23Mc z9;MtpmZEyD8A}nFT|bs$qc@f!aehZV*)421Et*BAHy6=2KFHTbZ! z+o6%Sk$74xrM6L@=^_W5rclAEFB8cY>LB3xA^tKvZ>^mBG+M(n!~dl1`HkX-q|2p> z(PEv6fgoeKyhsrY0d$Y~Ji$!0ptn|Wtuse+JQ>f|7==mfvW?xauza@*(_<06M`(` zOTm*qVGbzfh$SB4@r1i)&lgvtu$Z!#Ze@?~G>Py3W3V7AC@t)IGu^|hFfU1S!axFs*34`tPr^s6TUfC~Ci#zaW7Mt|^!-f55ry*sTJ zp`A^6DyvDmiEs73DByyglMwfLBWyHrZSLc?fzf1!s38NQm4hM0@` zWI-gg4e(+6aIK*StA<1a#v;7QIy$IHQ&kI$p+Mjy&QruiY;$(iffe*~qefWoBuKIce* znU8GCt;R>2TbQVleKD3LW)=B+K5$%S6@`>pPZYGw=3@7!nZw2RGueYynrqd1{9|#) zXUJ5`aI|p<+8+FcI?gfm{con#q=cEJ8*N0=E&c~6Jv1uSI*4Dagb3sx@DB7ohhZDEX)ZMWu|vBwUu_MQ9&=DkYAfzQ zZch@TI13+<%&>feKb8y_GE}91DsS|Eyxbjv^V7!#E*U$QEO^`iW5&vFt#iO`&RtGV zqr$3ZWK+-R4YN6`&E}GffEA_&1~iUwF2LxXlD%?qHp_);tDy8OOe4USXsouA=~WT| zBphvxbpi+z9fVD^v-H60eIzSrodpA5mAOb zLYj(Fykx=6DEYEH0-*duD57-dM;j&ZAMtl?l<7 zHE^R-o}9fQRyeAEn=dY&cQ8k`!krDSGT0JzkggG+2#5-phv-ezDSQi7x3DebWcJ0H zHSmLfG90AJqiMGw;0QC4!9r+FMy<)=%Dq9@Ba@gZanF^2PxUwr$g9^wR&`{fuyqnU8Zhy;V z%*F<7wbCuLwZx90q&UeI|FO$DXN$uZ+DhNu`RY-!u#@mo>S-)46#q_f+YFG8hmEv+ z7saD@P-mRld}cA}5sk#6Z)>3`cC67@GI*O%6c7)O6c^%$JBnq>^DIh0aqI$-aN&9v ztsi5xYfljxIX<1I?<|_z#E*@ioVh_CHsESv>4`=qktHuYOx1S|a@~mOaRo-<;@}?y zUWtxvQUXMS-&FEzR&^=sX8_N98SemA;7e&3@Noy6wQbbi0O&mCJgBy}s#KQIItPOX@t?D32$GERGy~3DlqRK#1t8T416X!TcQ@NYjT@W9Hl@pd$e0a@FN)~F!I*a!M_t?UNz7Q6fN2F( zKn_X4W(1}$jxbQj5EqXc1=y?!(pZL$)5WN%tqie7!l+UV00#c0b(N<+@-9^MmTtlxZrcK$3T;f zLlb6#PD&*>%11Bk5xYeYnkegaRVsi`u4(P>EyP6+iA&)(%wfTXo z4Dy%m4D%H12tfbQLb~`Sh_%rZN>6o0P(vS4r1E!n%PQLnQD+XSN+QL5RH#dXqg{N; zPd%|p8Z+KT(L10AZC1$3)!&+LE>4 zVr=lAG$!Wv(4i0F>}-jt(49c3G>zl0nkxo}jGWNBz&9nslxiJ?veH#Vh$Ffr1I-eR zf#v2g;$Ot=WMO%ojRtlFY+xN94e@8UdAEHeL?=Vza z@ViY2YhbY3zT=^=v``5xQHOxC1YX+nU?f1|Fai%C0KE=1E`dq4A7OQ)+O1o5s$NrO zyvFL0_7M7~Xi#ahp^Fq9npCjP!vjjf8BHw|=ga3JJVvQO1b|Zy`-{N3FkDf`{8<}D z-Jov~55)GFD};ez(4*HH8Y&4Dj3cdPzF@sB5E$?&*v6KgTO=BCt}zoC)1F- zaB|M9o#(*!`GpZ%Ol^wfb2)AyW^6Oe4Q_^VuxYLAAgz@`fcq6F<4xoPDxJxv7v?eB zpjD>K5)Q2EMFiF>qfD;ZPJPgh%6pnvykDm*I*hWHA7%S(wGVlZ5`h*Lacy{n_^l|Z zy;HqZwuRXn6%jF5 z?W!?pU1P1}Ot*+~f;=w}5sRbD*DN&Cw73O`2-=eQ!6c~3nO`ZA0JD@#ni!CrNm9C* zh<0RCwuQ@bWJ^XR)hvuQ7u1I_Qp_`;LtyZqKtq(Rsa7y^BR_cgJi*)E4I_)32@JM_ zK-Qa(@Esv@rlk(^<`zaLASrQej=mb^?5GOXz2wc1K<-NH(VqI)HU@84De;Eb>wwvs z5{Cs8rF@Mx|+uO2y%vO2hthU~?)pRUmK} z5S&uBcy??zad<~f`m9OvjueXG+A+x3O^=ALNFMJJ| zEw%c3Yxruv+$J&pdPjJ*-&51O#$WFYulCC|596tUchr_G=GQP5&>F=XTW_-hI_-d(qT~;#VJD%B6`Fgc~y*7Le znJtyC*Z9{x;cLijseHZ8zwQlRLuO0m>-GNirtmdnwp6~p-@o1xzJ|<}%GaCy>%QCrSkO-|9V&W8ZuidU+?s<_lB<_v!(L&ZvT3J_!=@>DqrvOuMdQ; zA+x3O^?-kUD0~f>EtRhi`qxLo*O1v#tFI61YtRQcR6fX>n!-cSU!@PAW!5y2QeMgL z)pNEk#vRxtEDlWsGm>KxxUCLNBywxGP~gW0ZMj`*S+11Kn~>a*AwNkIfo~17Qjka# zuq_OrpEO~Cx?OtW^Q?b&i#=}C-Uvbsp&P{Mqb6KUk^oXjj6OlR^@k1X(v{Lqa27=2 ze5RI2&<*e&6r4Jg0z7I~v?2KBGJ_ZqH*`P??nmkaEF6CCQgt|R7-4F3b0Ap=c7Poe z6WuNoCA_4qOL#jehn-0-A9QleDhZ#BN%(XNuzgFtmdOg#5mcm!bsw05D3$VHZ)Pyj zV~tR0J}H~`7x#a??=D8^x#bR2rrfS6cy52D`6%#}p=zfz$b_KKBo5Ius6Re125!Vt zTGxcMJ|q1H=^gNtT4y4jBu5W{C!r=9bmOp<1KqcQVhzjuZpv>ufgHC|SL=#EL$InE zS67)9`YEf1m z&XqdGJY?Lvp!Jebw!x7S>}9DLgSQ)9OZl;aqs*O2Y6U$uzL+Zx7$Dv}+u*T2=IdoK zA4jTJ&*=g1i-FWfJbnW?_jI5D@if40&Qq;?+MogRiIq##*4<3^)vRTs9vETa;01&s znih_MFP|gYp>%RWd3@HG+Zhd3l}UrOcaRTpa7>SoK{axFQAPu=Tj;2P+xVjM*T2yL zeMaT7&vX6$r-fKp6l?;BY2}+TlX3wi_$Bk&FiWAy=lGWMT4`EV>)m<`+|;qJaQXZEp%4+rg?Q% zda^3j9zk+tm79BHn?!M3FddnJSE%$;fd7}8yVFPqB8c-mX zrq?qDm>>=V97)$7#>^_(zcOpguxh1#o6#w61w&d>WMLj|p2Bj5DSrh$(^)Dr zc%DqPws07DtTvsHRy1}FenDidk#Ckhhc=ry-eT0=i2{@zp@jT7LWkWTg?XIm1{NJOmX@3Qu~Tv=XKKbgYy1uN8#%J%g z_!>Urn9=-+v#y$RwPoY^v4v+bi&EKzyRrnTNpSWCTZ1e;q@jA0wm6|1RprB)V^}`j z=!Y@AgvfGaf$Btg9obTL3kWaWArJJ$+bBynY|w{9=*spUCJHx8VNx)l+``PG%aRw# z1hG!|9EibXsrHy`KPPqs?+Ys81olNSAc3Dmewfh&iiUe<>9(qEsM=76npYu13Fqlu z6B(f`srxrnQTGj!(V2-7>`5In6womqy^r8qBNVu28qq1oPFx&;0|iA7tRYFTA`rqW zl)S)T%L>4I<T!*V?bA&K{7I4@dsusr%)R!{|QCgwfDSslm`#&-{o~ag8Y$0n%{5*|^)a?E26_=TK0*v|MfZpP+ zwq}wf6HY+?lEyOW|3RY)9;}7n2Gz|El8}&PUfS{8Y(i+rUx!U)PzXsL5y|0?Ikb%R zCcObwmuD>-m?EQj4t$c3y969W@#mT{=r@hQJ$j1As*{6^wfqk&^lt6^mp3YO)nj3G zrp?{*ut`0sAL~QhCu&u3zry}Z=Z_)a8(sZ>Ha}?<>`la|o$e#N?y@Mrj|yBmmX=}D z{qF$=qX;^EuNuWF`8x$<=IMr`uG9nn^`{{pI`S!DzTe|z@Hu^ z_MD?sQ;R@g4!Fb75MGq0e6C2Q22IYlj z>45vjTfxXT)i6SDJ&2Jy(w8~$gC*FK$!X=RS_^*xp&M z(IaLZ;6Vwx9Ve^>Fr=W`N5D{SI-(d0l`Ae=>Yg=&JKK3Skc&FCtr|~^`~!GRij#=q z)qoAIU1n4qqcRW%@6@}@8f_zD^$;t71qJM|*I|c2puYGrWI!3HE0kFTu85_qSe*A1 zqh#lME&y=aB)2{uBmG$cg-1joCV@E3dW)HN^DMvMk1hNgN(o@i2L0nn?6h#L>%) z7!1&w?@GZ!;L<^YmZ1jUIbTB0*tY|1vF)bphf;mzpfmWk%^Lu~?lINhVKG(T94ru- zyC&E_7F-jY9j&++c0EsHM*#V1*TncD4Fpy5_KB)W5TUv{VBLUVLIA4Bva*xV>I^J1 z3qf~~6lLKAXg*Hy#T$!@c{X<#fpf4Q4Ymh|nk{Q=BF~VHs52_ZpE3u*YJrdB9?WL- zoIr(UhV{=#=t#+TEG#+=7SP}qMImC44WHmK#7<&Z{OQ^&_c@qcJkOye@%KDgW71+M%k{KN?&LC_d{QJ<6k2hy}z1=>|C91wKo4!|>S<@C_> zg%_EG^8>R~k3=9RAX)4koSJ(e*tj4E3Zl1+?NyRC4D(MJ?%T8{WT-Zf$8cZvJXpBz z3Cv;&XlJ}htvo$B<4iW=`c@Y{FXaf|IV?2ntjMSp#j4?Z(P4I{W%x+!N~Y?xH+C16 zw=sa6le6_&5Vm8EWNoWOT;am0I0|2^qm{VX->638Pza-b;N*X1u+_XK!sN=0*a--m z5FdSTghlXSSP@}kJu%l(TJ_{d&^~N@CDSy%jCa9J*tMha^!6K~GLUbSWIWb!bYL7u zeeLThRwll$7MM?fcx$7@aTXl0?M(Io6WH2O&sve5(=7mj`f!stGqXdy@@8B5!%yu2 zL^@f*KEp`GOYF1CA*$>s>~=u_j>#dN$cjfuq>1kU|Cp+~FSMyMq^LoSj|d2|WHr7i zJzzQPVi(@-*PAxviW=~@1*L-b78jjr0`N@~i|^=|@Ud)%)3vOPOX;As08cdA36-rc zv{L8b?|nAvc*18of|%#&Mtfv-nL{+y3}&v;(BNU^KY`NCgn#@5k9lnqqOyf;{W*;U z!RhK#~$)zTmNVti{tfq=K}wp^nwl4QFKfrVx|{w+|~zk;J;a7azYF#Y8rAczzr1n2e(d)t^?WQs+IG6+Iv(2Cj$fH`N_W!MP z*pxlsTbPA3Z9}b5OU)XG-Cg>EQHl-%7D>ghCrXc3Q9v>2pGLo(D3r`-fw>Kly;Jg} z|HIZ~GGwBO@RmuFCy(cc{W(|O@8}tkr{}k-TzJ0R>UeWw%x;N?yIK&F2i>ovt#P$1k86{WLFwiugAw=CWDE5T zL)RO;=9>m8jkC5q9ma;Cr)Im*!)DZ`VvJ9CyHKrb@a98r7y9mR{`++e2BalerA=l& z0Tt4Xq6&9GQH&y7uhJ12U)O7xR1)S{xw{He_Xbt?KkapA;@r&h>%0@=?wn*};2xzr zhcFItAGvc9cjpl3;3?X}EO(A^r;mDdpQ`D8)pj?K|IfKU?AHYgZEC$!11`en(FdHw z`he@z1WGmFK?{t>Jyio9F!zA#A|H~IPQ1|Ow?u@$gvJ`KX)*UjPz}5!4GY$a)FX@p zJrbsm3sY8fyhuIDMnUf!F+6dFlAfgA$GxH&P3b*Gsgi!CkC*3I!G0iSb6u9_kMGaM zjwa2@Q4dFG`?(3;q0lL_S8c$BNqn>V>ELXqS$QEkSm=bOqbI80914L8t`Rm2_Kz zCL0F7rS{qVVlGLu@JAh^zXgkf2Tvd^K&cP%Luws1AK!P`Q8tuf+ju5iluW7=^ZoZV z8{Mc8SMv?pa@7pgO7(*wdKr#)!!MI9O0W0hr#UG$Zk}iCQ1shHhvQ+bM5nOhm}N3H zxfe*QipBGF;B1>MfI4bpIHhVb@GtN?9Odf2uM5Ag3BRuhzds&+Ulx8}Xus|G@E`4T zihXP(>Tt-)8#!JK{f3nPodm*$H9{Sbs{5k6LE_F;f_?QYkV+w9e^;L|@IQ8=6z2p1 zH@)Y+NrsDIJkD8l zvF~#v4ek>Wg1)qrT>W31s;-ejr3=%(L|5t@3x{q6JQFms6g*dDkD1$HX3Aeghg&O) z$PdTF)^ard2F3@(q+7BrYAx^Th+&50dRJVhc$6!$35 z^dpLUI*xdX6Im!l#TJk zP8tD63O_=Mw!N?eHX=obY4d99ty6{&e4nZJLv+z|y3i>ZjGf(-GqhWI0Nm(8;6fME zG}Lptm{w={^n@Nl7e+-~F|wFb#OXpK)+>xIbmNWaLYbk9vCK{v(>1zq1ZXKh&U-sL zoT}{39*8#}gI*h+?9MJ-_5vHg3m(hXQN_1Uyd|Y^Nf`ap9kCXmwMgby@rf%|ebVM_ zxQTieM1~4!BrFa2fan+3MSLBJ;#x~aqRIEPM=#+Pb!NIy9eVj$&vY6HMWR>UczF`~|I-N#qtwL@K6R^5ogcQi`-g zZlXdkeMoq$5fZ)=6221?zDnk#^3zk?9aSY{c-)6qu^>Exh1rC z>}&Q><@j_WKe*Ugc))WxYN0%tKeGX7S||(BT%K}EF_#%w2q9Yxt_j91*h~z(riOJp z&#@N0fF=_ZVt26cpffjULickM64WFQ%tecbu-ke5VG47_g<(b$U#eEn1*GYFpD0cV ziki}_3nR)bmxL^A0gGACL&mcF?CLB4HJ0V#u`I}epCLi|HUih&eDZS|=!Oq4CVXh; z9XTR66tEBU(f@ew?0yRl0%5>)HHE1J5SCN|otVvC7U*0O{>gR=j0K@~mn8?~6%9MH z2rA|?WnDKAAPv_IB(kI%*nJi;mn#Jvl^*Z27^Oj31VS4vtC+Ddho}xl(laIo8x{*P zkh^)-28k7;>`nYYCCsB|Bh^ot*9sqmBys*Ax9nYU8Jxsl4~)O+4nFc;S!KAJl(&?x zTU)24&!v_J9)dtmO;6$RYM2&}FQ&<6LHSeZs~&a2^lR*Cz|$-2N%vI$xIJy;>1Fn$ zQw3j0exTg_chnlgc1W5GTn%~w7ur|fyrX6oG`BV#(ue={upo8#1gXO(9^~-pjIsdV zHR^Q42?L?2!kPdB5TG$vk0C~gT>*Rbs#DX1*u94bt^+A>9Y`TI0J%>! zlt2Ow0N%dL7!ka8^#Q&W-(OsB9l6a@p?TvdRYx?{5i2KTm+H`4oA`~v2R-){HD+I1 zdWAK~j)Q%RuGT(cG6Wwje-%I^bJ93|8!4M25S`D-7!60=mBB~Xs7&lw0O~_eCQ$pn za^yhWr7|mk`tMIBP!Ij}kps1-4ip0Vvhgu1bzdK|%*QM%j|I(iNMJdwGMz}sE{$UO zivf}>e%uJPXJO2E(ts&JLznZb)z}rN`Iw_7jNX2KySHQU;Vk<3&ZvqRo9$A-xnbJ6 zAXWlQzc6i?{Vmw6AFtCk7lF9|(3eHM>y?G?CrUv=oj>X=;!~{bS*VVC3o^tLq7K>S z#$kqB;K&Sf8qkhg^suvT@e0>BgGa!U%+kwb- z*t*Bm(WS#O*g$U9k33(vncAi|5^Wzuq#$EKP7*0AUIE|d=XLt&R_*dww#&1(OGN&J zcIB_qAM-#Z)&sqmQC(>HGgZ)8)FCXTLkfPWnl2$T4IM(T!}r*(BVnos)vi4`2N?&{ zODTGcjeCNb`;umqPX~W1vWPIHh&X>C3+}*94e#~ZR(g+q@$HDKg)NeJid5>3!Z=Dt2IwIdbfYj^W{e1pXtGWaX3LNkPiOq z*xM~*Z~x8TKHO^bqRoPYt+2K+EEvLcPETO9Tra_YO~3yR$Z|*@^-rh;b@~}N`7yRE zLUAJ;Kq%S^^k@wNO3?hXpTST*>(WmzW1uOwJ4K^Y-;N}cb!{GhF|1AL#u_2XUnIn5 zV*DXmIuIj#PDUeb$YQ0%$m3wvnztURD4Hc-Yf&T~VBu&`bJ97abZ{IdD^kHk&94&jbQ_8gF(rHq%)=(vig6nHA7spI)<|@4_Y`XzoXw(O zq#nDlM$^p6VwW^zW1KxYh&~eV9~a%!Es(z?~vFb&T6vc%L%ip#Vw2^2JnJzu6@15A~${Hj4Z0_5ME%uYdIOub(gM za-~Lb*XNn3+q~4$Zl3Rdb$D6g<(C)3%XiM4FaG5EbF>gieFy1o!CB$381Q2&bH2b`O3O9O@)iv> zGx{uL*|sng`>#@uHzx@)6ptNbqC!mjRBShAGqotQvCUkpdGX+*P{JTwK_MWEtG``O zQCEvc>zS4mT){Az7*TKp6rvgzrN1&yze6-=cjr(m=RMxF>nY&s4tD~3DwQpA86iyrx?vKKNRz^SODr(r)iWOD%_`-irQL& z->w>2|N7C4d%}CZr2+u7;bsO_4Mw=ohHm3}6A3VKwz9wh&%byHexL8-OTBn|+g^IPyP$U-k|31H*lBd)AVMpK;rirGRoU17Jr z_~Mrs>*CA$7Z4aKLSBlrK)`Q6ZC_!%nq%J!YQ$B;i8T#O=n2){WYwwc?1ro$>2)NIgj*jpoI`8a-_J73(PGSb%Bmjk!p#%6nw3ZxKluE1L_ zeT&~NM8eO2p(TBDlAoSDPfutWQvVqQtqireA1}-KQDnEgjTYfe#|NKY7H?HU#59Dy zmWgP5TCA$|QaM?pE4~o0!pn0jym>4I-Du?~!KWv>nq^;HjmZ-W-xazC|3j@N{qYd- zQa_jFf}cd@f~-jMe%$LN2+MC64d|a{Fh>*#jaEJu(!4ntaI$*2no{XcOt53ZHGgT? zT2bsj5YU|#!I8)UnVOgFqFo?nx1bq))S>vxtg2ayA)Sq`Bw@Y_a*TOFZfD|hiM7~& zWj`1fi5JUsiW|RZO|M71+c~|R;(hfLL`|Ymsk1>7<`mF_b17-+ez%lc?^AiK2@tSd7Jelr|1jqNi+jxlO|L=k6)@J zJS(7s_uOJ+M6F@phb2kUF?=zJ9R@lfKlkzi$vn)RLf+@MR^T6^Kd}c7I$93W135uo zc4U27Z?qJstVZ|*`_`jlqlFt)Z?r0@-q5z@5pz}sO6a#GnI%`E0^+idas(moC=-Hx zC6r5@JL$i(Q4yLJ+gpLq5c?uDrkU&U3~k&K0>*JVLWi2u&#%!z%P&M}6*v3H!${)D zKbM+XxY^}*)RRVDT%_U_;sSBFzujs~c`&63Oie^&xGC4D=uE_6E87CSNSsKbHjDd= zTbS7sy(N4wrwVpxo<=jyMJq<;u(p&4wXpdzp+dz5;hB;{$O-?A+&NYxuG}*%_|rk3 zNJ#2sa$5DII}~VoAS&-kap2kSpTh>1!U6LPS&$R*kHUpLv7vHGL>ocMd14w9GbLu8 zn8id6P~|ErPsE7v;`kj~MavUgF_9=5mc2Z&UG&bJX_AM9o@g9BRQh9vitLWrW9h6iZibQD5wS_ntck_}JE|wNSEx^=u~j zFvullLe4(D1mw1d`rIy85t~wOD7Jw5zz<$Y0A`qE38oS*FiCx20n${CLOwRm+ggV6 z*?C21iF5+%dIg!KThc8QOr*T>qXkS1QSz2eWAx}%GdO3WrD|GxrAZZD_#2x!y_%8) z=2bJ2Ij9+F0RT2Xk$#$=bb9cI4&gf*FcDK}Or@4mV=AX9mZ+VsXdA6-I*l5lO=&sC zU5c;TG?EKqg(l&*D~JOXU$H!mNqJ<6Ae+^3b7d!I_TRNi`wBwX5C(h}$O$ZL!v{RO zm)hUJr-5i^5)tX?su&KUN)`KCfs!|+gb_rx0f)&7ux9|10mN-mDp6{IssizP-F1R4INrGhMF(MK0&<&8|xE z6jUi3P!?p9cO}B)P<2%b4lX6B)(gf960DRYUg}B`G!9Lio-obejoK?HU*o=-p0u~o z;G#UC-{}MhMsA!KrO-V~XG@W@-3(-^Y9#_vj9?_7<%})2W9oY#Aew9f72q(I`Y|I@WTjLQx6~H}UW>dfqLfL= zEDVn-FI97W@$~>uYZb_-ry6wIM_FcfGeDNfiXOUW!0J65`mi_=S_t&PuU2XJ89*ka zZ;tc<45n(M;X8eF4oM$27;Dmp1-Y52Tbmg2n~ADnDS1x<yW6dl9n=l})`FuTZTa<%A(l=RZhh>r%fIs* zpZVNTKc|6e!H8bo~hNau@dCt-e z#ew8?6WUm`9Q%J~&-bjEWxHkBbIq^6{psY99X+uwMa)`P|N8O|eCBD&$-3dBMiIAk z=#rnk0TNF8#aABCz?@j@(n584Lzv-D!N86`bwRk}mx3VnKyo1~t&^&63UBQKyj^%O zU^D3)K-?}sAUW3n7IT+St0Zl%Hdak`T{iYqIt4fA`+o-t(Rh z-}$afwThoN*jxUAjODkxv|(kff(Re`II$!j9dK)*d?ZH5 zx`R`&d2*ItJc4DNbK}Kmf4pwFnB+FEIbRFf4#l8>le3p`Mg^a$5?lY>E~IvYpS-;_ zy>i+0nPls_T_kS4a(U~A-}~lY`?>cumxlB}?k1hcz-Wkv+<(&tf8~SMeIwa=Y3wS| zuz7MZdA>-m2&-z$556dDr(0BH`DKPizR3V3?usL|8pQ?k;e-kb93!-g>ePNq?K9yb z1SrxPj7hEXWkRde5X$=aeTjx+tCv=-=E)7kDcsz59sr;;UM+EqOt;mWLSt*45v-%m zeDN$4^{}!*M0c^fTtGQVB^$zr}Q2p+V^M*!YL9zSc^uW=~1i>Ta81^k|jDh0zo?6xE?9FekWW zCWI?wjnu9YUD>kP&TFKbq&7Alj&pD*%;q2rB1NwY<-b)7wp(|Y@FvR zXEJBkOpI>;a3dG&ql2JjOmA?6orumXybVPQ4Yilb{x*#i9aj2z7!O%&D;hV@O#jHc zXN9RR@TKvbVk;-0kcHv~eTI3Sp5!ZlvqmG%(S`M=An!`dr-=uOpvg}}q-;Q^nkNsD zNsXSy5ocdc90I2hr)j~|VW5Cc_-ByuZrEU9*o_CHP)Ky06I2YJNb+gN2}{_JpKR9t z<>{D}nr?KNl8U!XmoyxY1>l#-jaXvzIc7^ss22ZZcZnY6c>pSNdSaub;jY&(={8c} zu4j3CyZh<7LLLyO=EepsDS{#Nwb9>J;h^sSl~L{s-zG))XN99qOZ+h@AG^!*TB&9< zQu^!EV(G7IR7W#J&wBr@lLvw^Pll@L|4-wwxYl@pjHhf!p36K_m``phInx0DH%W4! zuICF4E1HBKgdhxG{+p!#Yu)JLr0hImi=(vg3ZaY3gOnAl+)+cG=`b@}$0o{ykap&< zqUIVYv)ByqTAUrV>p0R7YR9biz;%;}+JmU;Drn|8QfIBZ_uddUjQT`{+ktXYx09l1}_4!* zT3-AS3W642wIyOokyor&Yjqtiu(NpVvPV1Hc(mVn&IxQ@z_~Z3Xc$UWNL^DocB5z` zHpZ4eKvaw`?L#^ywWueMhoPWRJW75xc(blLOlv4${0s%12`HHS%~3G%n@}+6LmdSG z-w%y zR$dTkkPWI1`ePK{64u&MMw|mC3|+H~%#SK-^jr5m26Bzq>opdmqSiuvri%&7N3wT4 z7j3J|rdFBoJSb{u2tIig_%(rl=8LjPdYiNS(2MPm>=BW~nMlhWxD)Aq#l z&7gqTdfFjP-X4?*SFpJGo)o|yRV(UbMnP9S4@)1Sk!c6j90gL}R6VC?`PuD5LQ9}^ z--11>G>Z7fsaeZxq4u-+oNb&^X1KrY*N&Mz)P1fBuO|+~Nt-woO%*nvXM};k=msBO z#$XcI20G4TK%Z?k(nbQTyy7O^oUkns0YU=HN?c_K6k1Zyj|VXEqtzJmiFa*cvc0Y; zCe!zPFaX(|{AiVoig*qa_{C(*MN}-VQvHHl^^xY#X4N{l5+p-gf7fGkbd+@njt<__ z;T(gRDlV>Ty_lPAHk%Etk<1$2=ZcKa377YMJ7fvj+MQ-bPg!ti@=@h+UXyvY_y*4^ zC6`{x`?vIs08f~GKG;Bl8RP?m!cOdQjDFb5K#VQX=Yhp>Uv>n*C3lZn0k=hH9tEs|oH)&{#c9f>UK@U*_7EAu zaZ2D*v81sC2t^WAo9;wn+H_}TLti#J!#Ta6z$gVaO@;02)Y9~2(gxH6D~&61R4rrP z@vN6I(!#0}g*eZDv5pc6BttFZBqI?$Dp4;ctu>>K!5t@lovY?3eX<#mt_bhfSeFi6iq#YohvTXymDnmnLHn z1P>I_7;@ZGGR$Z%tN_#)6LAZWm{s*>6Elu-!5)~vINWGx(2 z*&yeP{5nJh3TaylBJE@dE-Vyt4+Xp^x9y-mi@voIMAWSfi*uusN=gKD&F5wIG`*awf5E=eWp zzqy?$s?E+|ls>`SPK!6;8d_tQX})(U3A5!br#g5XJ=lrSZo_?#GSzQ8!TN zrScB2#<_rAq{B(55}Q2{0x4pb#4y&T@zsI=GKh%gWvrmd0tIG%D59A`;2vqvI|`}x zu5d7PA2%oe<-@K$uq^73)&HfTYaYD9V>I!STUZnG#HxXCIWv2!X5~y@Kc0+4d+E$H zu=X@15peBd4<%=03~-*veihE1Z@Hmn}SoH&}rYQ7m zPkcv6Q2P-&@t)ZJi%c4>8l$lsHtW$Mj9@h=B2>ni){(ejfcMqmPgjpRpbHG+qIq`X zaz3?u8vc{Sj@NRgDC1o=m>JKmq$T~grIoo~?QhlKN&m8=(cpPSOH_V(0&|l;zT7Oy zCkwhOY!jA3D`KdXSZ-Q$ST+Y8(sLWU#*nAfgPhppAhL`Bd|IgA1ZFe~v<)($EiWk)VPQ?d8yc3O|s5Gi1e8TCM5dHJwe_ zQmd15E`-3j&4*w}A~b-BNRq5z(;zsghDY?mq1Z2rZwj=^`>s2JR!q(L5!@ASz#D!< zp;q)ZQba@F*hycMH)YYhD$n^kP=!@ToN`a%m5XQ5*;G-_d6O0=5x33aW*w#wpEopI2me$_zl z5<(;#9TN1;p+HABw=<-0>4V_z*`xl3k%evx$GU`(cOtUIA%t5S2Dyi91cdc`X7Fx} zIOA(^*)yyRoDDZLPl&jJqTkJ`-HM)>OVsMD0$H}xF(uowRlfOb9vZsR9@FZvQ9kNx zKD*3+R3sU|m`uxXpJu|hO?JuZ5ann%S`s(;)JP+)D-76&;lwDQh{B>QE-Q^86h(bR znXyjX;!ettcNL9Uz}?8!O>tc-0M6)3jj7QtG-d$;gxaaz7B@23C^2?ALF|q?fuZ>| zi@WP7k>sYx+0D|VE6J>es=Pv{(CGX|8&qR60+rp*zBqlInc=!)~> z`lop%2;(wcCNc^mvk6)tvk@JCzS#fyD=x#XLg&~ZVYCnBX9>9`_J^aQsXeCfCpkbrd3?=m)LPV#2zn6`Bfn2;dYHfZ0X6cJHETe2^=A z!pS4Vs1PN`Jz^LmhE=B~meX1|xJ%L!9q=MW&&aWVV}szt5U*0(2Wn0=Bc&wUB4w(! ztutG>ty7zlhfEYxPC$~@4VvunWKuz%2_%9UQe5T-4)I3xZQMP{3TsIvPPOfbE%#CA?kB4wn71Xxm)_Z&wp%H z5>@VHI>V}`wO~euu%TWIB~k~ukV8>4cyeO1P+C|z5Bt}2=q@Tzi+~_hiJxF#>)8Rq z_%2)Sg>bt|7wAc34H-eiAS&j&a=-NNz1;}(0&;PK273x3kZ1i#U;@A& zS-|Su-4o`#xdqo~`ZR`T#jf&$u%9Dt8B*4SuTAk4ujB0KuhUEswj~F}G7eN+JS(g! zSg0#ACRa2qzADn;s9C|8*iFm~R4e9($HNksMgXM(LD_Z~BPg-5Rz=Vftf^y{*Nl3E z`?8XU=HTJHC}%DBb6ZLdq)b3(n~+MyIXM^w5s@+lNJr$BEw|ThfNH3Sy)Lpp$11@v z7zbCHYRG}2Ws#{KM~PHvlo4?OAH}l}Rv{ElLD8kn-R!@AEk6IG5DLAih}1hZMg>PI zr+#ZKXxETRM{;NZus*3m=^Kqq0;we8F*N`_2M1VcKtD$MPSu%)KQS-8oyA~AudOI# zHy~-4prQ>ni6~-L@NOM=yrd}29m}krD}J%qLmUB=)ZA$&L?qB6O=Vk`(sLl&Y-@KH z%7hMOLDY#sO4HEqVTfbnENiP0fB&R)8=iDny*^Dr1K-_Fe-FF{5*#Hr3YRAtBBWB{mU!qHc z`vvp~I*776gg&8ATYs@FI3Z?HBL#%ENMj`Ia-JgPjvR@{xL2wnyjDAM%4mUV1rw@O zj<_RdRSt`pRI5dDrk>MkwW`to)rt6Y%>1TdW@-Zda1IM2*lRg4Q$)!HG|4v#MvC9H zl4=UfT=PX?=99uqK%7hkd1^l#8nA5p^->;7i|bd*Q^I6z^BXv)3I^B_n>^`T-|Dyt zC|i91$1`DE&#d?ruw?ZEIPO(Pv=sLw9KbQc)&Yxl0LMM-Q&7K)k)o=y;=Zz-wGZHU zW_bWd1=WfJII0g558${*D~tEE4|)K{f$ylt5G_ntv2R*YY)M(mWgX#*|qANo8`>fQH zhn4$ZHfdA7zGwXPI(xma(Y}Q289Ut`du;A<^)f!TFTohod%kPby#yOA(-W(hmtd-G z&97wti`idzue+C!aq65KNyRwKcP(Fx2eYF+G0de)u&dKcF20y!Jo>k#Tnytf#e5(+ z3Y74e6acMdUX)-vCE6Cv_?UA#Nd|M$E>*a-uf$0C(bUA9hB}JsBPPyuyB$^%Mnq|3 z)&d(_@XS)DmLsqfbpH>pi|AGB3A5vw+!pCWoEmEYO66t;DWPhTO+9%^@TD{Y+_8%q zDXtaU|B+ES@j&4nU5PHB1^dK$b8<2|+e zy|N=hp;zioh6za1@{5l30cp@0SW+(~X%%pKfkk72UUjF|Yx-e}I;m`?RUKH}R?>eF zuC#&y4f)OCARR&6RzEGBgokXDhFkNmjHuj?F~IN76vJNX_rHAmnMkIkrG2a|-hSq} zi;L&I_H~Q-;zjwnuXMAU|*W z_KUWko+oc=3=-imevW{|4A=5qxcxsUeeMP4|Htz$eD(j!-kS$f`FxM#$eL`~rMhI7 zecvPd5?QkEF0P$>uQh9yY(?246`@qtib9bkB_#VEvL>=5MSbVF7peE_^?HB4%kQt> zt31v#Gv}G*%$ak}oHN+erxvIZ8S@IKqVmM8$0d?chQJUVvI)m`DL6 z%0U3>V=n;r_ww{XA^Clf!=N1-&`vUVp!Rmtcm7Bt|44uOBi+A~c0_nULxNkQ{Go~0 zK|0x?eLNuIqC7G42`COtHz+`OAW^m+D1C;{XpQc(}l03sXiQz1(aAUeq^0-so$T)zSb8F*r6J)0P%*TV$FwFb?F+Y;mOcl!|Kl5burQ>h zA)zDxHw!Q8fVICPBYcIWrNR1_ zmexTy`2bb|Jb@Mw{wKtpAtV2$gGjWUJ60@!p<}pdXUJIUN=qAHsEigDMN9ruGaA3x z8}#X)Fjf3fa38R2cBIiC9fKGZ^aKdFzv=KEDgH+k-J4bLg5hmwkl43BrtEjx|K9jc zr}oLue;Oc$;(!QT-2a57f?fCk5AZ9bQ=oMPJ>1~o0S_;D{!bT)y{8X+cZ~pf2sEaT z2eeQ=5>n#mf_f8xaDjB$ZaM>`A>Ft?4V6R62P|M4Kr_It($Z)TKOb8!Yapw*xNTry zjf16aqw8t|!w3@WIB>yt&;t%Tf76vf>;FxC`|1K>Yqv6ffDZ!?B!>vW1OCkf97^y& zG!g`lI|7M>bcrJZ?gqMOLrhGGLjm&X0fgFjKzq3%?708kUaK)7J!Bb6bzGsbm{K$!-!p+ zKu|wKa|b|hAbNkL0Y5=@RuC%!C>M-QV3iJH1r`nhQVp!qV!^??-<|=uklnSL)&uGN zb*b-^J9(mDemNLBRkgF&7UfxF1T) z)l0(GMbO{HRU**G!`TmwwD&>%ZQq20gM(PX)L6SCovhtFJ-w_E9&jJ1{|L}3t8{QM zF!sE>z`B46gIIUE10n3a3W*7xgs}qhA%Ngvl@<~d3=Z~y`w0sQ3k!+-ZOc-U5`ZxK zXrT`nAEM(fZLaR5|EUIXP{S^M%OBrw{kQKyH}{QV-|IgNN5lyZ=!39_#DbeG4E!wT z=9lcSBd~#?rQl-=13&xo(I`hrS6dkPfpR@OQPz%NS{(vyVc-YK^0M_o!l61nY+>LB zn*|sV^9I-$V@zTY>}rtcmeYm z?!W>=IU|rT@B;>qc47%)1s}r^zJMUV4H6oZ2il!g8gTV5K3WI;gZll~bis@k*c_Nu zwnr6hGD?h0|8HYI3>Gg`_bx4HKpHGz&=y9Bfck!|{S!O55Tor_IAFp(F^diJVhyQY zFbDfsj5Rp;e-Hb=lLjn0Ka?Zr1TYywfxmzc0$8O*pe13qQv$Te*^@_xo9p zJ^<3Yw9NwaQ}`pT3ev6!Kg4qG?VMe_n*a~mgZTk<=;ID|^Yj31#r~?NaHrfo0ISI% zzQWkSAOmbs_mbeNXi#r5fRTW&JiRcp>5TZbxq&n?Sg&wDz|YtjUCzB50qt_IO3oIx zyP?IVcd@Wa2dv!36Jd!HnGs7>m-mfp4D=7uzq{js(hyHA=VnB?2UvUgz#S3(K5$zH zYX>`P&|yCxAgcGjV~4eujWJg+DQI{=K>-KC4!XUqhbPc{*lpd;#vLdCFEq*-?GAJz z*zEn5i&6N1tiR`ChzI#6fcQtkkj|cHV52zO`T}Fb76F-57`Fu{gkZhDMJyTM4$?3U zsL4ITbDjjM4s5$^!IwZ*+@_?&u?FME^lK04|8=7>Fi7V@b_5d@CC)hjy#R!4D;NyR z9x$*uaCe8cc>fn8-8Ed?;2usW=if&PoC7hSO=rwlv9=W!4LjEV_swI+On8_Q$7


UQE;-Ddpx5{`|xI?T!lLxj>@b|EdbKpBLO;%GFQM$Ik&J0Y~{d zIt2JTi#wtJpwf333+9>5m^Eqcf%gM{^tCWk1qPnAPTkOr&AP67zY zU|9emnQCii@8Dn$Tx}S=hq2tSR5XMXEhGi^FJn94HUSSeA2>GBJ%{q|N_O^o9Y^`%4Q6VicYbP=bF|(Q3as7|2i_vP-S0qa`3gZ-(sJHj7WM!&pL*0zv|hVgh|Q0)Wk;66f7 zIp&uz^dA7|6E^`GNmt-+@4> z0pYmk+QJYWV^%``%vd@~%$^2eXAf*kN4R}}y&D`@RFH!V1?PvdA;&CmXz~N+EO6fe z@790CL_+>j;7GL8y+nfD)sAP=+8uZf z5MbPUPAsq=3SxDDqktj=uQ&ztlo+4KpEfitQ1FKP<^va`p|!O;KX@Pwtt&@pQ;Pz- zT4y+L4ch+u=U)o^OM!nW@Gk}arNF-w_?H6zQs7?-{7Zpq6L@IF74zjUjeDW|= zD8ltuuQ5Xdb?}{}#Kb!pd4M4T53HRV97h}Ek%BUPD3%fh`xO|s>-UFF?m)Q>z=Ps~ z{}T^;w09Ad@1NIjaMljttATU7eU)O7L4Fm$-yh=<0Py$oNgzn?uMbK?<%%Hq8RJ5S zVSV5`CyO}5e3Y1&A&44M&@UlD%x@uZSQ?9Y69#W_(C5E>s0O}+>c#My7(ht}Pdp|i z4k1IIV#7ywTf)IXfp4I`t6+oKu&0{XHQ<17@Zdy2GlPk{+gAkeQ^0pnJeUS_0)jc5 z`0pRJfp2)gH^2CEXN|#p1%(9nj+-%6{$=BPN6lb?L&vh9uH*cF)(Odu-z(hxZ1;fo zf8M}J%&8G{UK^zrlf;-NSK$qpZQHDRdeNMEFiT22Lj6O(5=Y zZUP9zKTZ*VP<;0z0HJ#s-2g(o`w>7c0BHoV@iNB%gyQ=p0fcmhF@OR9M(^a`01!I! z%>xjszZgJhtu+7$)!zvq)LtKe(8=r!fKc3y6Nq;N$4)rkKpL`njtEg=;^XB3gyK^) zci=ey$w1nE2YT(mU;rT*dkH``0Lyn^FMv>cBLG6}LxJTW$PnhIy6e~|^02N=#@6=3=N zFO&+Ta%}AofA!5y5#VV|w5iYUd&XUf5B2!>5+KGrkzo0Of?f58sU9PTe!cy*?$}c+ zn2FqNz#W9e#Dt`F5O-5{P!#fid<%qKZ zt?Ivsp!n;U3>+LH5o}yC9e|L&;@(N`>QPCM2BDKUiU7g@v;`2d-~ZIBz91j^{!jfH z3-Y18%&wj-0BI-=`tS7ZLr@Osxd8wnJ^dL#sQqs{-;s!7^&LHcP(2&~LibRl0fh9V z7J$$_OeX*#{fgYlj|33vcP4<49q<@HXz$hlAUA*uJCH_<5_6A6VF$VZ2u3z*zvH{(s&n#}~(bPY)o}Pmvv{3m`O(Q5tN#TfH6P=DV62;uMAGoNXK*&yW1rQof5P(qoX#hg~%m)yn zdli5Xzjf~9j{*qMFkvw*7 z0h1I`_|ScGVD0_IeXYN|wCn?SLVzoj0hn8O;0CiZ+KwN@|M3Zdt(Lg3l$3*=6x?1? zSVREaWO0D=xgb3~_@E6mpCG?5Kgb1Ftw4!@yQc%VX@v=KO9uV117m*+9%#*5TSKGu z0Bqw1KaIJ6j)U6{&ADunJ{@{W~0z6Q9 zw_Zu`{(n2<9d{x$SYdu)%xEFz1-1K`-}@*9;qBm{?Z6c_EqH(d+Wm|tO2xwy?c}Tjc9=c^I~az3a9eO=9%D}E@2qAG zhn)-qXIme*g8}At*=`ml0czY$@A_AF(t5is?xgpwjqcp=G1$fb-5_m@L=751lX|42i8 z4V6P<+pW{#4;(PXzt!RNN7{KO{r?ROK!7fw08EJz2O8_S9bZ0ph5Yrq@&W8~u-?qw ze~)4p-x%O40o>g*YA0@<8Jp^fJ9>D)j0{sUi zxcGpH$xoj0;;+xzhCZD%Vso;Dp0Sa z-!3AiBH#L+ZwYVADJZRX)4e~^$#TCL;_eBp2eI`-hjME<1GgXF{^6JKlY zD_`G;lJ!jaAVjrhO)_bwYL+&CI#^fdN}q}AtuML5_)WLprS&m@;p`Z z#@gHV2Xc41=1bG(oX^^)5EfG@xtU8!+QQK&PWRcqg$|eH01aK`pB773yH4k)7v4C- z8+h&c2g8?M5AD-A^bUQ&WulH|Hj^PfU2)YiMdJCj*{B}VI`*Z5qT$|@U%m0VvyKXi zOr8|^c2)P>;Sp`kXS`wwnc*GraLbtrEMI0f?>xE9JNsdHT1`sj6(A#9|_Tm+%= z2;OhW?Myj}M6xcl53pmSMWq%r?(4he)xGf z;3CiHbA_K}w?>Z?GFgt^66qc+CHe67^>H8W|bnj;OY=&E~W_wP-&4N4uXXdygwqsZ*vq`^~lC#E-O(R}%}v3A?^d@$seO$*qR=&$S5sI83AKb|ZY0z)A06bR!0$ZR92VF^divb)8%zsqUUk}wRs~)HGoklg zr#UEIG%+g(N-}?cdEi@Vu~iPfT7OK+aFe#EPE&$tGwQD4eJ9)d=&OMnEjp|pGrRG4 z+r19myxvr+n#2)6cHM{s;ZyYSjsiJZ>(3Y0RE|H?(i?NW_Ttj1rvZV=DxKE@le8bE zJsSAP)gzL5isd0(l(2?O-{O?Y=^79Cb~wX|W9H@uaUpiaj!*Wcm0yV&PQ*~Z4$-ut za@6k}{5VUq&OU!wbnRij*H!$i?3BYi1O|^BoXnq=tiCYh=@mFz8ZH>GwAfpssBjsL zvJ~Aaldu0gkwHU#Ed1!jB|NoW!A-forwOwjR|Qx6dTp4US}HEpz4r4O5Hx5_^RKvh z&4YvZ;HgK^{yb}!QU%wg{EirKEj-c5DMsPEG-)S2ZxM1)dA@o|yDhnOa798^+UrR$ z71Q=q2EoGjhu6o1*gx{E-qg9DC?Iofcy!#nJE>Vu{YlN}YLOpJ2C@+Db-dWg1)F+gn_x z>%V2Vrkl$A)Z{xs!s9WetQ6+?`ODGCM!QVoUXFGPj|Kxbo&k|FV_Sq>)FBG6h-R%);El8@7HC0vS6+KApIsF^~U_{7nT#UhRkI z??}Sg>Vafc#6+$@D)UiC9Ac4WubznPDC3_lb2q&yYo{mICCIO=@!&Wq9-6x<#dYiU zBiSqole^DPdCsKdJsoc~T`1689u95P*0RpyT`g;CjN(RK?ngf0kUZc*AgAui5Pvbu z<7;|hex>Bu*rc%UEX84pFb`#V{*aCH&BA=CG74$q+CD57m|6!U9(PSE8T#nft=UGk zDt~Z`sV?x!8KY-=vSQI#MSm-23C784T&9`x!qT5N+WL)~PJapCg3)R3c2R5XY0J$1 z>yf%f`o&+zhkIy?&T9nDo|SE|7_o9L%0w0uw!9(W4t)FEQMSG_>!slH_E}p(YMPqF z><3FvbZsLA#QA&z%Zy&!{GJ!+cRhp)@5kXmL1(o`4H-n-f$}Me+tN7hG$(k5Ql4|0 zTdrhn)Zip$un;Q0aW71qRFNTAYabo6L$cdU3K(&}k-DdMbIDMRpkjR>Ra!~5qfD-o$wo6(>Y(&zIpq4_HAR0S;|8<~(}V^> z__!$XORZ=2(>m|ZRMJbnKdFDw3|B8o{n6MHkLL)6LG4%BO}CsB-8rBY)C?Y+eDb>MGk@)pVe%MzO&ObTTvt!}hc6QB`N>noe&^-l;)K0u zzmeWs*Jk}L@ewcLa%D>_om-2ZvZ7spglJVx`Rx)L<9qnW2?F&FyLv8()E~DX^R4{Z zNN!6?`AY4h#988z(xAvHcAs=QGj-YlWkNdhGDEF2QGa3@F)9)6(HpeEA@LFowC87} zY_>SVFE#4ZT~a2nBPjoVaH%9jKS)6?MX54oBXL1(?y5#p{7CCWc8iw0y6b(xws-mC zi)Tu8DoO;S#ggp0d1N0Dr(Uj`Yl=IR) zXvIuR?aJ8OcG*D+HM9(&To zYj%3w0-w3+TO#{X<}~;paGD%rb1UCH6=7!TaL`LJJghuGOGY%cH1||uE2{Zf`x6}X z(|(Fo$RO%(p&K8iy69G(icXx$;+e4{P*7`xe6x70e(ND$5C&moIO>)XHm7kbH zd&Cv#1vgY{4NZ>(%|)pylGrC+!*{jfY5N)1SyQ}9oyb!eVq`u_!_4eu=xRC7xboJK z=oC*{Lw{9hIgxB)=~~&BHf_T->5bA;aA(uN$PDwl^Y zd?~y8y$D5ts_K(5&7Y?|a7?j6K+{Kovgl}O&ZjPssf$vrO%urj|Bwx#1&t)fY!vYq4bynfG}fAD=ZZGhaH?8$R1 zvFpNu)(_P#)W43V5N*7Y+H=0|YRtS)h9#{TzBfmOX0rFHE$WK^Nn3?lMn!=~#-a7& zpZE=x@((^39(nz|E-n7VljoOu%gg(oWcYH)sW{1>boF+3fl1zFcM(J3M1MXyltuLE zSOW9MfX2HE>}Rx>vocikzic*r9G9@xwy2vd;ZbZzd{~h4gf4oUw>n5-%K}&>USkAEJ=z;mt6j$(h#Tt;$?;5{##k}UgAik=PncBDL+x9j`BMog6na17oX0qwD zQN4ET(;4E1EjKsu8D~uiv)7#@iF#nEiR^gBP>1@1P}w!l_!GeKIE|aTZrtk#ZDRx>4huvKenF^w0tQ-0DpF zc4l1e3*YX`DF#dqQ{r3x+K6@L9?x<69t92R`Ex0ETcb)jmFTL@)G-~=QtIN^2xw~H zEPkMyOir&P>9Ee6Pqcn3xjw1<>9fLPCgKO!Zf$oJ4-c=BAA3VdQ@oKZ;`-qcHw$}a z-Fs_OXO_3~qw?LZUP|eajY-an?3DfoB0u7E=-RK`eAGKONS9F+cc$wNcXD99iAiLv ze71_5o+mZimj{N^$~QW{tdJ}Xd!~GEs*1#`)G}P@h`V&P6n1wj^NNnBNVs29t7_qA zkz%%gg=8#VPYUI$krht-U2b z*p<^aDj53daeaHmaQ)*bs?*Fixl*wGTblOT2s4dwxXW2dU}MT^Ua+MxwF>y zYzf0|`FstGi;>By3$^U-WiMMpU(r*&o>-eZ#;w)Q$+O_g^~UHrE_3v-?ch(TWO}=c zd>%Gte%W)n+NAmuTN+d45n&dT&KtK9K8%gUl`uJZ%qs*&9&{alRd!>=jaynzV_9!{ zxkQv<(8u-CtpfT1My-z~B%_OXil-lZV0r(1YK8iymOOQN#aL!#DqdvBm(XGHn{yS_ zCGE5Lvd$cNcI}*1cm%5UF2pC50xa4^d%mb^1-i#4P@z~lWb$GkH?VWAF_PeBIs57z zBt{6lY6<^t=6UVC+PJc2SKj6M68gr`lR9iwG0vF^xCmwnW{QV$&6hn@kC^sUd3KA* zT)H%ee>UjxlVYxsV>pqi)%QBaa@j_*-2z=~aOV^6$j340_jce&L^Nn=bU%JmQMiGa zeAZEV7@3f?#v^>3dLm&o?X6~=(0o%r5sdw;V>RGed$%}dN8V>6aV0qEDDR<~vDKF@ z6JgQeFm~4qX`Ll!4)Cl;UBf#+t>F}FvZg0WF5qKzbE{@B4^;p!qX_AyYjV5cb`Hh( zU=k<4mvn)@5GHDH{3}X5WR6UbNaq<*C<`6#Ss|5>x_KVeiS&2vMOH+37ugqA6*6%r zC*S^1$o#_WlPM=;GiZhxojpTl4 zB)oi{NJWD!K>_3PntE zxNz^OyeUE@WCq@)A2-G|Byi9|I~#7lNhEC?ZRtu*9l_vVDCS!RF|SGnMG*?^m0t(5$qYnGOzzWDxPZY9$v>rUPh*};M; z{FpZCBggMeqDWKD4A(U3K2BXt2o)W&BR+QYBK_hIDVy%v^s-p4YgG8RLOvO^ZH;yZ zS99ODxaXJt=B`oH{Kk|>Q<{zGf(pf@rySB+norrQ2X38a5@35Ikfk)X)a1&3(DN#M zP~=j#<9bcd^G~7)PY^DxvYo{4xs;y42c<=ch zsl2_BQ6Y1s*Yw5GbP_55hT;_S%2)KFRJyhq75%qZwT35p`OU8QFJ2eqUi(JhTVj_% zeSok9`LNw4FO}ltbz8x*YZu9#*JhaTB->8sY)WZ~PBXuC!jnBnUBY}#tUmht0%vR^ zUY2{XsJe2C(6OJf9A$@MVjh{Db0-#PZTASxVAjz$$g>Tdw{d~{1fAZnit2bN^sLP3 ze7B>?61rk|XA7!_%iJtGiJQ}=M%37Siz4K}1*@m;X;NKj#j7pP#a5my zaT{$GxH%z%wz+MACl-2OO&<1Av{qfjJ2XMWpFF0HvS76>BfT}^<4dJ85)L+3#nn;{ zHr5!nDYIzYRuu6klCCH!yz+hg!Y9F%Z#6`3_3Jp!Y(&UkPgTA6gofJE z)NsJePfjQNdrFSPN70aH%#-cz%rcF*amp0^-DlpDE@|L?bM4@LpjOS1ZQ}ZzMzi;F zbU-EX(Hr$|mKMrXwoQh%&!|2;<1+t+(Kq=K$^86gC66hPgBpLzj0!dPi{+&quVeM#&h@# z-Gk7M-h;lJ?_=M~My1-3O$sht-ncdtGX~2;r6cG&Zed&*78E^>U(7cV_Au>r_p6!Lfk3&ykC(qYHd6XX{|4FV4<{U}X}?Wo zt(j1eIkjmIoM!H|WT#+%%@ihAA~N(rI5X49MDMh_-LY#g`3|9_NBwn<^<*urJC~oB zqC0GsB9B8u$Jnj=ZaD$>(^2MbzudBg>P%TJG9ha+bmP@0+o8|$K4srwUdH2{de-vD zs{h-Z*m6!B)hf}?{^hsr8J(xpMiwV%SW>#`N1n7@dU2}pcAm-XfnM?O(>FODPRJ&B z)Yn->kX`>$onL42=qGGjRWVQhd5cj-e4>fd0sFO?3BiT)M?d_~>(J`XKU1Z<_Jm_I zfN%Jd>BBenym@2{_DZ)G%93BTpRJl2<9N{L(|zX|!LzYQ1JWUVbVXrg&Lg(D949na z(jkTl5Fu~t~I-g);5J5*S+;E}se+?D?~+mk zrh~t|%H9qd_c~j0^tkCurBypF=R;ht8dynPWAcOU$GTsoD!vO3zU0156ZCpr;2RTT zr{Cq5B%XM`drFB}prz-6~YxypgYkQw1T+aHd&8 zhxqHu`)MvX;jyqR`elmWiS&GP z&WS+7u&2mF99*B$B)9k{y~n86H5fi^jh69;%zBh`Q+PKlY41+ z8})i3ztIBcb+KY}T^FnE{dogyyx_idYs7 z2TH6sErok{u&%G$5v?p4c|2f*-&HB;gf6o^VF1~ZD3Qqh=_aPm+d2m`=t%J1H-_|5 zwM1Avii;t2^lTi6A&4P<(d?;ha_s4*3a_uWpthOa9@FgVR~$f{FcJ) zuFe@BhK)nWIPdcgua?V$PPIKcU-R~mYf;$)0Rsf{4+`I&od>Q!wJO6 z!{N|%x-Cg|z4_zyaZ^?X(m~@PFH#eHFLs%=#R?Gx#Z8tR?#s(_R<+#0UputCuQc~Y z$Z^Pge`^+gq^cM-s(D*S;9bnTJZUmrqku_{n3#(0`v^ZT)8}+abI#QUm*SDvl{UX9 zv`>CE960uxn0G@6@znF3iV3x`xT%Lxl)-7Q=_$dWp^FQqw^N(RP+o&#i7^MuTAxzm zie*OHXJpv6UlUMG?|RjZe4Tb;@H9JYO34#`Ysvu z+=w`rltkHFX4L#171xc7Qu<(<(-_ZSr@3tTGdGH{@v7+|OGly%UsAuuriH{`| z>mRwLxXPp8`tHAbKq_bT>;36D4ukLKdIFU>1x#m+V#(A`v0A8Jr5ozh zIod|eM1@>TUX@TT)qd)Tct>a8lIiLG-scU0V1^W1W>DXyXO@Jo`hxKlAG}k&$NrXP zm{QC3)xoj8H(wnFn(0LamnnJ57g+DJEHKr=OVeM*l!WD0`b|b03}%eUU&i6;dgHid zvKiHH&nd4O`fB5t)0ND}#OT)Vwuh=XcnL>Sn1rOq`Y0^Phwd#sqi1xWY#n=Z;XLXG zX=C~a6QPgxPwVB^o1F;GAKu=M3OKMR9D1(y_JJ6$X7Xd)i)@QoT%+%;%UAfL2UZ6U z%i7Ex@Ebf$`?H6fPp&Gv33Yw5Wu7vHZKOPB(%0Jc{!J9|(0Ec`D6&T+fj`BWM4seE z-4Xi>a*VyQ&8-Ye#7P!EhS61 zt@J$aTQ*_2j=X@w&GAg&x}K!j>ZSABx%|F`$JO%=BrO{x9U0j=Oyn3WT(@e>B|Nj$ zIO+JoC%i$D9hQxkztGWoIxB<2gZ@QX{&DRKYC)e!KAk!KZYit&^sv7=DQ9rZ0=HIY zYrk6XbKKZgt9-?Pi8kYK; zi==qBqe-^|eDyL9O6g~?7~80PVMLmXB3_=w|4wXBFQ1R8I~1RA3gDP z_4YF>7x^^9Ha8ME8vJjZjD)U_SwoTs!Zb3kht>ORs*0XV)VI%GVQ&91szBT_Ux}l# zNb`B)v~-f>kxk;YK}JQXcRYobp04G@oSLHs+kOgSv9kvYgjyHHPn}r$;e4@add>YD z5nsEBD96lF-dN%p(&Fn{+zXG$ijt<2I|Sx@Pb!C})drR8ja#{1ofuG|T8T;gY?z)K zFN?l5?<%2Y+2HPBNTW$0?kP_$YD1yQ-g`L1)JrRp;$?$FcA>O-ckv0^j!L{j?<(ZO zvUkZf-D}Qdbg!Zf(3fsewV%kl(!163z5|C3UY`5;UF_!e>ccf{6ycZb9JE>k zbra4D%PJLF^3~2od*}Ndd5?_E>$i~A8?V*EiCO#2qSiCoiwR(;L!?{<9#_c-dlfXy z%A1v9Ze3P4My1~RtnAM<%p%32H=UJILaG+jaIWsY$?ZC%p318VpslvE{h4B2|I5{?r-x$b0!M75YbkAeoD$vbXp9xg*;&=t zwv3<0)|u1epP?XNpIUu}kW&bM3QuZ@jScm$#T7xz6Q@RqR;1)Bn6`Pzy3&qcIrC}i zlvkl_3%%+b+1nY5A%H7Hr4P8sjG*=3(UFrV8&6@z~@n^5Pp8LZ#rIbZd%!UheJlJSA@^Z4IhQO%6`ti{4xi&FJ(mYP_b)M`HvR7npNt1 zmNF80y5Wn(T-@Tz&>uDLQ&y%_>X0<47KJG*6szB3h3-|-i%{k@Fvqz^YhV5hBcJc= z3V*P5I(8lDovS}fF;gcY2W(B?GQZT>YV4dCpY^EES5f)xl8l3)f$Az>PCSp5v-ZLb zx|UYu))RC(VRiJe7cZ<=jN5%t6<<=?gcTW_O zjpTRU)s0e%jS_byh17g#&#Irv&5E3_rm)b zP6e;5t%ZVCA;D`G!_Mp8QW7XrQB_}atkv7T%p&N$d@w{|=z*F45FK0bi`sSiRAaK( zV+&&C-wkpbJKe6Vo~Y3yTUjtGy&JKVpW|W3MG#sknRHND>|Ip-E%qR$5Qd_ln6nI7 zf*R#nc@_OLHA|cX{v)@~TQoR+Jt)DR=Jv_OgUDHWKuWX9$j9jldD>&Abjeqj-_sG} zJPIhkp!0%)Ai+zWUQDru(X0JLNBEmugr!tCBR-t_d_?)>N9ZLQ`;1op?A9akK|CeR9+@*=}DTh-Qx-oAS?!d~EO>F*Uh4(xu$g#ihoslRvJ1vhF=!`IIG5u+6>0 z^Fn7tWP}Vt^lN@xni&H65UQr?_P+nRIqW{Ld1;vAt# zU9adouW)Klkdvp~W>Mux5j`%cnKY2A^u4RW84TG#P+P^gQ{(0IlyZXq(lApeK<;x(V_@}ua3AR<>Wu<4w>hWGd zx4inea#Tx&&MU*LYzD^oSiI}(wDQC2G7kIz6 z`5q;E0!KGNS_S|7n$m6K7G=&*){LsDYW5TK%Q08q^)#LnmLs(HqhSm<+3m6Bc9HJ; zPx^!O7Ysf+U09n)Tx5GWdf?U7tt+6g!S5*8rLD4(796sZz}!Wn-d z@Pkh3+1#VrYr02gwx^DsD+*=~3QPSWoYj`z)%=1vg+V?(>amvbGt0=2V)LprxTUim zIYWoz{btp!ir;_Ach=b+#cBj!x|)?u z57x`SxxtmX?xVCdy4X6jd?z|Vi_}K+=-G%>v7WYvomwX@Ja|CHQ&z_7dphG)T1Qym z>X#2ULzljY6>)1;pY-uQ(YE@A3RmIYT<3dpgLe8E_{`YxB}75>8rGjkKdwo`F%cCOAz6ap4)6D zSxvd2_vw<~g<}+V3?JUiihkt&GFEvx+~vu9Y})pr_hYOR(YGGUHFNeBlx7lySJDjB z@Np%)u;S$Z{Bi6&EjJ6$Mb|D0u`<+Ljnap26W>3jP3q_$H+OcfoSIRIl|q4OD5A-= zCSRN{490x>BW$|q^Gp=;h2fjDRBkFBH^z={DXYYjiNOMM%ZfZo516M`ds0p5OnYgC zmaxv?aa`t7JU=sexANd<>d~(~+@tLy)DOzthA$g8WtRt>J-=XD9hTwcHmr62I(5@< z!|Cq^Bu%EgpPtOidA2+kcT#$CsrG@wWGkV+ft=qtbK;qB-Y}<}E#Dh4H&Ql|`%}GL zo=BV}_4Q+yzC>HcG~2iAcWHX`XUvg0dgZZ@g!Q%f+n?^PpMYafsCALSHFn<`1Q($MxO9zWADm1redX}O zR}(jpwByHI#cj_UT?Bam%Pfc@6?$@rjLSIewdIVbq=_WB^X>uGhlAMakWQn zxr}0^G_2Rk?#|P!4$EYjigk@e9u{l2*Xn)6lSJ-_`&N%kF27jlDKV7j#b@tETL#^y z9)BpYhCWC6@%)purvfd_EC#ySs-MxPpA`gH1ThYk4A+LbroXg!R%~PYg23BZq4rK} zA8XJW-UcD5+!x_KhRq&k|CWHap+CCJr^fPJ%=50SCwJ#Fc0Wb$4Kxf>4V?<))?^-YbbU zae`SWyaPXCeR_tAQZJ3Z=lgINDSe~%gWl8o?dwgI*)AL*55`ruJSF4r%A7y;Wa+t_ z?qXz{AJ=T&xAJpEr0Mh5Q=XjpT4RH>6q_%eQ><@vSe2v8C@#!o?+HBApPCc5eds{h z7&4eo-h1$w+MwToJdy30IOmCS(+UF;N<8}ScY+TNZE|?NUin&8`nc&{q(@!Y$@nah zEz=X1S4dX*gbSx#hdgfb^VCPFdkeikWlduI?XZA(=ujwbDvBlN#}`&{K7!X%EiWRr za?i~(scP3UP=r1k!M|y*;pielQC}2sXykKh%;6sl_5S#8x`iyPydQbLX4XrJ=k!^6 ze(U3TY zlfug@Th@#dzSM0n_t1^-8!R_Uk`~ABBp*GytzS?5x+IitL!;riAn-T3P-YLZA!L+Ehjc&R)L~Y`l8poBQHgwJ@605rTN+uN>c!qC} zvqg2NmK^V;d7Jb10|m%BIxF9;-}pLzT(pTcb{17F?e39r!ds^&Uwt^D+T|8&{^k5! z^AMc5wawIP{S7w4H=JU(o%qm?^@&+oM+jn?yLo%Y(_?w$2k%{2KKkNFKsvd|rAt~P zGH?728q<4ch8dZMo_%7}`~J!M;h+=jI28e1=5|t+Zr(l5KWm%jOgJcJo1>Dr<5iQx z%`aKnZD{6ZeAyCx;{B>io!N9Xy!38jf8Do{5rrG#;%#o^GAFI@W3RFJCBAd`vMxM> zZ%da(kNyEyW+|H z^3&}Sg}QLh1kG&9H>VZ|1LsOMjCk)w=rHwqik@BXz4zi{mLeN>rQ`*paU^f`y@y1u z?YEr!G)7&r#EzS#m6js~76j6sD}_?UQb)`+xF}E3t+3f$=6OmREzjW9AzE3O^0dFG z`_&68-v}Sc#UfKq^YYL9668uZCx;^@PoiKB>Gu;j>omSd!fOpRFPRu!XEGHx=4ToB zct^gSZ0eigws_aOwacgY9@EYqdPtC^C4AG&#QWw%)R($Uyl0ViHH18f+2#9bJ%%qu z0`G==fAV0vIWO-7s(0bySL&~a=6t`ihqAek1%9f$9H@VE>%k~4!*zckS!i;c71yti zP`VLp%xY>e_>GHd(csD-4?nLJopnA>!g3^MwyE(bZL-|Wdq3~IG)@sX%4#(;E=pMW zefV8PJIvcZuF>;o$f?v@$eyc7>KWP#DGfg!do&6LaWWe$UBEwVGnx2)DM4+LIfC}{ zjVj^QcSbCvPv6rD3+L)mFD1pNy;S6u$i`(Zd28$MZCPH8o=@hby>xs`J1a!sp=0!r zoOPf3sz?78i`ad$QptD3q6`TvigXf2la?eI8dKUZau&9Wt+3-0*H)V~$2?$BnT}^9 zfKWImB^Rw~(9rwy8%tqq$0o(`%TElfXv!=Lo@vvT{4Q_WK(nx8qXX$+KrBH-xNQe zWH5dq*4(PrA|o$;vo`8`N2=0PK+^bwiNy_wdS{|kK`L5}Nil;i)TJ}o{K{Lu*FGV==2!e%T;9BRf1ZBo zFeN7%FNtIZ-e5v|#KCGkN#l-E@T$y|-V(ih{$Ulp__xQVyEJ%ENBlFLs~cI4zgc-d zt9V?CuS5EYalf@@Dp`~@S4^G78!FMDoBb-8Q7kP!PtG3Y)3O$RT0p)0HvFph)#0X^ zsbMCfzHSY<9ClM!Jh#TgaTz1x7t3V=mVB&wu}9@3MGDVX<8NU!T<~_jCYtO zKLG(dOGcoVH2S{ps{mgkp67R*WRLkq%A_dH{=CjbdNMO$mLli-A(3O2R+4?>1}D|+ zhEu;*8Wh90-WMlPWh#?nymN2 z&CJZz3ofK;z8adX6gqdaeN-ao8dZmUSY@JbVG(+Aab4-<~;(a5k{O8PuCMm%k`;Cs*B= zmPN;9Bn$SQGV$4+8Zmnw&6c_PDgEaZP3tBmEfEs>!=$mFMV-a*4Nc^Idg^8Heja|u zz5e~l63v9OuRZGPKv{82XV!tZ&S+)UT`Iql!FC|hQ0RQXg?n)@RT!2 zalD84y_w_YQRX-_Mbk>B1uKCudhzDOu>coeP8PYF;ld>NwMYB#7WLFsXVQbzV{-3X z(p->Tk4rvUQSw#xmV|Ue>-Fnu6ecz&WgDLjP&6NLv0c6UzW_Zz!oTQzf_a`NZ=1+I zJ*=ez!?~JR4VtS#5EOoL#y3i~ljdxrAWQ`}s-wkr+oL!`z*z^@riWqgq@+?~UWF{p z_{Lp0NN-L?0f)N}e`+rE_2~~Zh#h>q(Q($Osgs35!vglE^FnLO2O3{$@)|}UHdgkW zNU9?5W1wiS*uG~Gb24M5Bt*A?%b-3QpOKmXr>ix}qu^`NgETE>|w*{I%{TKBLLdPcuaTMpu+809WM4{?cuz@9@ z8&;$F1Z&C7UETiF>FvSGXMNf&$YGY8_TkFFCcu&Cyds&xQaM#~=c;Rj}h!(!;sSEeVI;XTGA!ZjNam zASzg0TZU3(^M%RvzxgTO>AriSfT%^g`c-(ND-#p8PU((o)G??IS-sj6muK(sYvi@4 zrb+&!^7Kj#8Xxl002Q*8RDOriMFApugw|w+416&-YJzGLMPJ~DUqlrwav;15Ke+aK zwC3jE6ffUng30_&l_5o`BWgA@iaudq$83DwVAzXt<=hDys>p2V_f_%+Wi=J^3lRVu zJLTifv|{75H!l+3rHLOOKwb@n)I`_3s};?Wo4E3z99}CrM5fH8^Uuoc!rB6OQHE<@ zpFQ=i61?+Q3E&tBrHnQ)@kjDskv=f3HwSt)5B)*%5iaX%)6~z@4_q^sf^u(jGeubM z3o;@}b~uaiZld=#r3CtIj68mc!S~UG5?2-Jf6j=h z{#m{vB$Y6WCg#=X<*=_%6YDzG9}9S@d=y#@xrvYnJQyNc^NhBMZUr8>GC!0nM}VI< zh;IxziX}eu7Sx9GZ>`-|OvI~G6ePGIs`_%Ca;!i5n19Yhfe_e7ZDblRI~S&Yeu9m3 z`G4FLNet)y=klr=s%;bpUp+o?d_ly;;kf({Z%pr6to^}xj?yn1+L@Zdj*q|a@3J;X zyx$zbOEm=t9+<@ZUb%71gx2rIEc6Pae{-6!l{Ozyyz9d(bp*riYOQaVF zwBzl~Orei%`FZ!IH$L^}Ma8d58HhJTAE$VOG(D56rohfD;|4uo%ItlvX0fU_hcsaq zQo)9STA9kiqlud`5_9K@jJkjnR6A7AgX+tJz)B)8NPN8#OLC|IH+?Fy>FE(hmIul0 zve=$81WPz8Cq>+#x#9>p*V*S+blqeQM?8YVkdm^6_zrl-9WhRsm}xe0ieT*)?iAvx z_>k&s7ou-{b~S4XReu~px~m|E9Jfw!{U_6Fd|LpPc6-GCgPZnCY-W!F=CD15C2 zq>0JCK#CGOPi>}9QPh-yf7o_AmpSX0vAcV(X1iCKQG0E{|7M$z?otH7_FoU2m^xDP zJ8Qw7-UsC>iT97<0i{_|8OQ|C)3#C4nw1EZv&cPe-g1H}@baSarnEVO$!S%Cd8OiZ z9bjd83--B;JCK30Pq+@oNN)j&vNGKR_1HnAR!I*jwkOz6^ln>S=kaD8Xqbb9yAy_1 zU_{|LW2+4LIy)*jj=2kkEzvVFQ41&IWkPqZaRg-s1Er-(a$-)}eAyK;KzkTD!&%c} z3hBz`Z>lttcaDRo-66axteRCJ$a?*u8;vxsUxI0!;gHNvSTy<;q}~-rFhi(A0teI; zoL|)Sr4IoF6TO7eqZ00D&KVx^tNa1tMq984x?J2*$M>`cYMt&zx>tjT0J%Nwa34>V zBrCLW?P&?1mXV*vzEQ=r^-)M;JVc;vjq=v!+Y1isBUj;r4T#ebn-2_=qx3$bco zw8`Ej5vv_BtggoOZD zpHwL*wFLNqyYkk*P))sK`zMBTOTBX=bH0b9;go*(A%xC|LSl7&Q{@_3B@XPeM9BZO zxkvGD7^(L6V4Y>*Cno@vtTeA?)X&mQlE}46QR#(rI5x;(9biK$EWCrYbzYhY>v?82 zH8T;syTyo011Pgi$q9S_z>$XyowO>WuiBujU?nP);{s`xuV%W-3tu+HaWMFR6&o}l zdxvBcP6Hg29T2+V+mC*4oMhC}Wc7b0kV(Z8TbN6gtxfT9abj2Nl4Rwm8mu!^v7g7{ zfpL68I!ey7d|np~TN8o8k1gq(UCLus0TWn4Z)uZ1aQOT#^)z^>Va_qFWpOaUMV=&> zx`0fTJTS%x*r};A5jc_`DoNojUt9ak>(MF zRoUtHq#0_lj*Uo;K+;oh9%6188tOby{k2PuL@c!|T9kXd$3l~L)EYD~vEg&_jud-4 z=!+-SR7KjhDhQ7X;<{##S~-e!>Q|d-bnRPYSFh`*yU)Mixe8?{U=mM33`FlB7u^ha1P7!Wfx_HSx>!8jD5jHCL}6)Oe5U9}`FV;gaCiul0)b_UH(-5lJ;A}J=nPb9{el(&Q! zY@1yj-+z4!5rtlU>1tby7uy(x%v8HX7QRX>7Ar3ugN`yB;sQ?aNlaxHK#*0Hb$#Wx zQ#vxn6!O$*ZtXV@Hqp^eUeRro^C1;#E0S!~Xu56yv8X^4lvR{JwaLbl>V9G|7eVgJ zoR;JRM`vY&n&Paovay#K`m9*>Is);_hsp1040QEEyjkJ9T~?p`LW1Km^v*kmDP(c% z3whIJYFZiaPbe6w4+${=Ywv@59gUWNM22&Ci@0IE^F0=qYXb9|P!YDlYQ?7MaMpxO zWQSk>2A|ax7AU`~Vm-bu&FT}S?=J-j4*^{ zpq;}|y7|jC7e>%(d4d}_1@Lqo5LiId5S_47VNn;>K0e-ArCWL_;7cyQJz{{W_ylC3SH`6pdOzU{Mqy?Puc;eli(wVU8 zgZ}8f{4|jvD#cJxDqxb* z4T0KhN@S_S1v$VbS&)O82u6Cv;2_Ty-q|6GDU^^nc7v*35euS{XRqiFCX+(Pwuxnh zDH}*4NUk&#Z2IW>csLEiN+9^%=^;mc2}_jr-PW6yORwmTPId%Ly(JZyTXY^nmbdto zu<0;mb;Msiw<9#a>$L{~1F2sgdNLO=b2_F3ugc*x!MD#pN(-yn$(GI9$0M$>`-2u)m?MA8cg@eG5ivY#RHDBI;z)QgB{{#cGAi(m87&rdRM zOVsKTa67uyefcs*=9a=KC$kCh73e>*N}0l&$Ubu)ga4m=7gLJl4bY?Mvn5A(=lHpa z=Bd;Y?s+NACqXh&yMh#S+g}t9z&PGVcRQ>;E7w6rub8`O2rso-z6XgHZehDv zxNoP79D<8#d*z_ac(dn9MZ8rcYgQykw3h)o`QgFj_k{1Y??_~umUTC)LX<5A5_K*g@xK3JA1y{8Kx8FL_+Y5`QR7ST4dh{1e*NR)2?T!eRqVviuk{@1j# zk0%}dkHzaPCRjbaq<|lW(Yss{RD78&o(?Xy+fHyarS(mcQ>++MPj7gU4xoEt-WuNE zAt0`u?*B`Un$Y3q1JJ2IXTU*P!EOBeJMs&~hV*`*z?d^{({|Kt76H7N19CIh;eh*H zMxLKR9CERIr8qbBA`G{9N`(>qOOjG-R^LNfIE1Y!rYLP~v0@goTk_#uh=F=;06=Ls zE>O3){#6;OZQm{NbycW25-MxKA+AirncTEoRIBvy~5o1`Z8BJV5%GLr@xn{!@Px6&o^%43yQiQ8c|HIQC70bMQVyIH++a`aG^3t-^NBe4oS&mrDu`S|Z} zf86ZR>MsT#@C<>+52Ot182){N4)aane1uR3C# z+|Zg$mL9#$aNcO^UfD^h8Bj$Yk3A<%q>l9SGuBi7MHbCF)Bi}XWBy3)^pB3_w{0%- z=6^pM&rOzg?Is&)zS-Dc`S_9=t(b#L+v99x+s?TrO{rN15s66Ibdm;Sc!Msr0dKsrK=(>UgtS}Vcd+T_b`s`^!BN-r4SJvBF6N9CslD1QxH21kw^chp|vQ>;>(llZCo^NRW_ z&^x8e{50?f##*TmZIvV!%77uSh|eKT<{h;j__qUWIE#nG8jGYE0EC;S#Aa?EpSecA zE@d2Wn_U+}u?Ks5nQv8bL5I!gCy9GN&u5dqHL^>B9@)IyuvSsrk<1|YORvJ-*s#lx z+6vTd0Vfd|?Oorit&0cgjmV4GEJ zQb8krJ9=#k)BhnLrB$LY5f_fiNAAK%>P~ zi*7E@ws1bZt##z8x*b+aMDN7_Ow5*^qYa)7&fJ~Wn3+{5v;Q>0G{q&w`tllcF%Qq= zAx+ziUh9op?yi*pDxAb)^SWyRN!983vfPl}RT+GZsUerc1ykhRy2#|i0!vG1G}IX5 zg|;QR&s$++YAVuAFx&%fR9(WeS&zPcd$yp(NyVxx-PhnB&>rsStx$G+i9%g`iO*3d zv^IGC=db%Vgk};B5pZ7XIz^f&ewrdBQreF7L3n#ne$Y}w8Bs56z;gSMc{MXR&bCEwXmmuq(6c? zS{WEtjSGT+nVQ&L6(o@@MMroFhgv%wX@=XG zQeg5fqPH84rz7f01p(iuH%_d!=rEwdhk?tEC%=qlh<=LwyV3G33Fd!oMiD#+`{K(HwOvS9b49yrQo2{v#Y78uH&!}!g6@D*TTxp`2PrEqO| zNuO$5nZkxT5-FcE+RQO!pS0*tE*w@FdVsvJCT2JC(O~eOic*=ZANK7FeX_2)2Y4w; zpF`KD8{rKvk?iHMZ?|zi2a;@wkze%3WS$2h$s<_T-i7{tE@R2Og?7=jiCu!@tC3hd zmQ=GgG}%{9Cqj&BAES6|;Jn__BJ^oLq`hE!1@CcaILrLsE+f_^_zvvX$1K*?#67HI zkD*x6_q8eVa`ZNx;Nr5N@7fcNHf}^`w(F;+KBGv|cr9{Rlqkpm{5UtIg<`2d*}p{La~XXhx~u}e>3 zrBioYZQ^24p@N0cm&yR%o~e(3hDcX$e8Dfd9jfadE8CSc?z^*;q`^+b?7-aM?H6%b zsJ-4=agmqEt#6-v;2a#&lyP96-iu5Of*wx#-{DNtG~KqH%sGl7Wq5G_G6XtQ<%bl{ z$D0Jn4%{j;)dl2ei1drz(2+{L1T_y}u^^so-yv9=-y#)<$ScZnhX`ra-uaNM0{QB8 zy1t_MmtzteJZtwkLrJtIuh9K&N>klR<`)fF`YdZ@%nBx*DG-}EvIpC9C;-Et{;49;e7p14QgRpRX;|i0i~2 zFRn^_i0=Xo|C?_Vi&U;HQiGj~2aS7>+5o&#vE3k~75?h)s~NO^P45r(Da$m`9r9&! z+v52V{m^TqzNg!(Ra6HZ5&I{zD+rwCii?`aWl6-!7FG(t0NEKcNx36?KqpUPz#~$vkiYO7#mfdx~gYUY&lx zJXv?>hh~4_UZ8IftA5HGGz|_#A@il|%y?YY-m9|^G*v-AwA%H@m$L3oS4wl zI+po9fLC&WQIp}B0_wsxUi=^Cvj#NQzCdi zg2bB;WB*epY%c9`((|kJLujRfI)UCa3=;7@@+&-$89yyqw~o-z=`Z0Z33PUd%bn~; zTMW)K(yoYO+gTUVII9jC8(7#@XwxX73Kule-OoMTNHYy8bl`)msSv>Zs&+htcG8^c zcxyxu$So@%`3xB!+VSC!rbGtqmrP@n83&R&Sp-#JmO8pWcNEJU z*{h_2arnsZ=(Q1H%m3?03pvSMRs)0zuxk95GA6oeCKNhyq21^`GkRJPhqsyKf{WJW z|IXe(g}}w}6~XUP$O7EPDQsW$`e!4$NrlVY_%({6%FNiVPJhZm=o*eXS?1)(SL~6Z zwQU=$To-bI{8S2j{V88dT8hH|A~+)GX-Do~I3U30KS4MdMhPes1&K4nSOF`ViPg82Y14w6&EJS@ zY619X@?0bFx}Ks@e>ST1DRuz26LTI{lS_H?@G?mR$hooBKU^|C3ZD{bR=)>5Ap3j| z#w+NwTcm*AY&ZoVe$)WcKWXDR>}0 zoETf6NvJu+kTwC)UOV&@5%g43lIBR2SZG$!bRxb6+mT`M_~z5QC7b8V7lC%_-M_df z*5iPD))LerRr&cK?VPeDVdZBb+5?Rew`Y-mrEUh#?Snj%(gHn*{h&(pBRqZ;{Ec8G z6_2;KDY9I>ksd)%OD0u2BjDd4$)%k^mpwEZKn2$025`7-&q7 zu{b>|hWnG>XGw5fbiryPOy;V3o=E#|v%L6;1F&2)cqdg3S?O!d4l z`HjctnoTg?@E8MLUd9_D{yP@n;X5drUb|Jkc{*)2PePiBKqzg*FC_cr7IWt0v6!h) z9)FL#juz&r^U}t=_jQ^9o)*7ZF%Q(gcX@cjZofHN8Vs4A0 zaSPJG0r<9j9=d+ybIz50CrI1pvkTiA6S8(XCV82XB%SxNM+_49T5K6NcPP!~Hl7Mw zv)X^p-M&K|fY|3pLO7OeQcp9Cemi2Wh zGi|+JrcnrtwQ2b9zoo{otINX)8@ad}v(KQMlu6+O7K_1hTyOkD~DFrG$wOB?cth0#El_7>3W2^$Hy7s_q_oPc~lhyz+%%8a#@U9?Z&Z zIxdJ^rhW#hL)r76hJH&>ki&@5X{w-vlDsbKRc9TxK4HMRjD#n}6GHw8Y}4=?9Fr-X zDA`qJiTX+|$h9Zs8uoJAg%a}!pL6S{2SZY0zYVUit`~8{*bh9W2)baH|7Ppe#odQm zQO8vl=5z=1Vm5uc^gvFz-vx`V^1M{aLNN>-hDz-47Nv2x6>Jq1YaHYPMpMd*)g}C4 zU?rjE2yr^5lS4dC27{p{65nRm{Cky%etyBewUGg`s~iLZEw0*Mo%px|l%AAWNpw#0 zFBzs9ta2?0>16MmSLBeByTlU zD~AWbUJt%5Ms;y@@Ba$;-PMMXVycs_$lZblz>f2RA&zdY0O?@=NsTeGGh+s3frzOw zh$z16!`ujPs`mZZPwl}?VSU{v?3ZpvW6zjGfiGHo_SR@C=XJontA(|$rH-bH+j18$ zo^SoY(kLA`t4>WNLI0{Sf?(HHHH0-$UtG%7TX$sV7Twx5-7Oe8u)Yyer=?(x)MGWxWD$#d*Mp&kL`%k4$n8!;N!b(6q*q^GkGCRFcV2 z2kRJDdM*h(K)(kJz;Gpd2006cUxZZZi(76U-AdG1K0nA(!>$j-Awa)T` zg&hIh3m`IfE>Yi8O}at4vb4Gc*t2k2IcV7FgqqldHMP+eQkG*KHzL?Il{xjQs!U7L zbM8?FF_g~6 zh=Ow?ZyjbLwzl|tQrd5k%l|z|)Y5s|2n-50Ux3o#-PYBSCy!*6Iptb>OHVFW4s=A|s2m|4j6@;L+kQ2SaPsU0Lc*Nt z%L|t5Av`O3y5nO$Wzx@RuJV?#a?^H|!ID`+46_Wh(9DU`&4)=nNNOfnFlhUV8%ax{ z%gLGxHCOg(wCE6lLz4b2U737qrfeyr=Cg0H|CnO#3o+J}+^!#qP;$6W(!1x* z(j`RB@YyD2x7aHKjW^{4=>dX2o&z=c=(AD_b!?9@zbGD4>XVN3vr+8~K?Oh2!RRYm z&qk)Z0>PwEMjxQPDO5(}*C*r=9p&M8etNVZsV8^Kj>T97BEH@r!0X&O?d=uDz;_%i zGR&oy!?@`HU=`6Mx0WGbMz^RIFz>P5_vp(t1L$n) zsSC49)``=Wb!a2c^ctq=0(46F>#^>TZWeZiOKCH4RpMO~O~15464AR6{KER%>6P1C0BL*kV5?+ZddfAKLDD)t92 z_VFR^B7MfWhgBNjBRBE!wN?K5;?s?=jL2U<`AbU+mS(yfv@MUuMx0%?#@AJTacg~~ z(j%(&(6a9D5(+cd1NFperHp8Z77VH%MZ%s@yEDY483eUcdB z+gmAFoo1o488bCukO#{`s<()78f$cSWTfTv$+s;=Uu4OtDjkDm?PNp(nj~G&fpP~F zi%+!@+LZG9jk_ZtO^e`wUs)_%Ykg9NbN?$N`w$MuN34a)2$Ty{i_zVI#F5xM5?)3f z)!ZIfw2s;G+_ZQb!YpcmP$nA}Hx(VmONl^?mFeXzKX zFxx1{X%p91TKk%2B(LHChjyv5$lci_kID~zu_|?%vtZ-M@s(Z>xgF16%18Ed+}H{P z;L@|FTx4DuK$c5OxxuD%hMdG^pULNiE2e6MLhh*|f3gLCbg|Thb;d%XW1Y8(`Y(MY zv>xYWh%9O*WDn89GY*G&r@%Wx<5Sv2A98(mqXGHst_G=xm{l;Vf|!pXyMCfnnOd_i2h=EnPWcaj!`CTurw&vq|XdeZ`|b%FlhO-zZl@Mfyr3nqGrh z`ztfs{l&F?gJ3ms8zooVK09OX61?fDz96X+J9`?g$u*eu-t$I#<_r~RKGl)R?llk` zw~vAB6at5LX{tBNxsEO$E_+yV)n|6M&vaL|*cBP1>kOrt0=CQ7^ikeu2|w%o7&MKz z9cHXr5e1zCB1;cA-LvS&v}X^%r=6-|grXJ@ndik$ zrl5FTX%IyT56hS{vkEG&R{aStQ@y5j-VZPzErn9G=|`J2P#aFHEtMtDqd6<#n2WXl z&M>e{d`zPS;XUy4gHuZUb)XDPUIdo@x&d-AQZ0{ej0C0Q1HEqT-_?6h@)5dGK_im= zxF_{6V9c3n^*eArsgPOav-HDZmv^n4YNE^d-mOBB=wk9qSqpECA@k9poRc%R$AVM; z?2>TSeOV8XYRHCU$6P1=7i|^W7sq@wR%|?h?{%#!yHUOXd7oc4Qy1<6oYxFpn0k~k z08qqAd6Be^8Tn7)x~mpMU^1n>XAZIaPv5G0DFEYZOjAltLA#iVVRa<;FYU%$M#vVRzOctO zTz1S~iW0_4G*g`OUDbUC@)+=DeyZg701B2GX2phfN~6up1QjLH9Bjr)ong(gTKw4) zdP+iUi0v3cIg3c~9%g^q%STVg)m@qbZ3qa@XlY63bQm6ox75hr;&dk@Q42NzW}H`J zqZbe0U?4=8-`Lly?e8LM0U?P=dC;L;HH5jR4PcXWh2&^=I}zzwOf4j_LJxYDx2Pv~ z}fMP}u1?9!8uf&AYSsEJ5 z1h}?2)FEZNn1_iBZL$kzd9^t~pMo;dp`x3qHl_kblXx#qijf_+NgEByQA{c=OOQrO z0)g_11h_ceU(9~cqcGeT$&A6K5w+_N(WiK}_W`#`r8aq(HuYGS4pnfl31l+3`qM)z zUjYol6L^<2DY9RzL{ASWwyT3M^IJ4cL;m4|O-y$OTd7%kf6Xl{8?(~~7Cp{L-v~^s zm-s5B93>kFjr(@d)gQfJAlJ_m^}>QhR(I||O1`h+#fsqCi0!B;R~Lly`LTB!NGTnU z*}`0JDtmELTd(^tmO*r|VEgoeWPB`;SNe88RN|l$2X~Gr(opO^2wch6oF3jN_$;*# zd3782>Xkf$?MOGpz3xLRwd2z%$32k0`$hm$Ia*_bUL6*ag2zpcmo(N?d?~T~ldVdr zSGmmnn{D^5c_467J9t_`2EoXJU%A9ZI;1kW-NxVoqO;Rd9N6-Uz=KKkyH~z0?sMIs z$vjcH+|xedcthLE=uhv?;hm1r)Hp^E;U~)=?|09K9+jm)2ek~oHu_QbQ;3#kFw8|V z;2u`|YdAaEBKz#iIRue_NRHV#pwQ!9++o$;t*l?SPP6VzeC4J|BOJo?O3%?c_Sor^ z8ZjJ<+gJsR-0KDZJhJl2MJ&ahg;rc%SNA<+j0*QTj=sU3FP=Fl`01Hcud>B@ za7whzXOB0qgz*8&UJWvx_V$ggeK|JRTQv0O@2~aq z*kXsr4v6~&9n6d92XBm_fWkMbbqHF5E4G?=^OOa_#f2U@?mp>ec|rwPnhO#|3Hb^zF_=Wxcl~agAkIPH zFHX5bq`b*36bBvfpmryX`)jBT@ojY89m`$yl0FdetM>?05!4p5(j^kiEPvrN%yDh@ zicKUwBV82gsd2^veV)&!EG-R%|32YP47TCB;!~(;`FJ>rg~PjVmJ1J|xbA|oi_}a1 znp15y^itp}PmbR-x%AxY7@aYZJFS!{JUZHw0o>7%nr0l;8Mg+3oOCT$aF*L)O)$$^yTlf?Mi2 zlRf|FyeM6)tbK_-)fgq_h`0v?)!nQ&2r>_ug8qS`59j;5k6WoMjrD!O>WVQbE!yLY zVci3L9U!Xd%=2v!7`@Ym-ynBL0R*G72Y;!PE)KjvQ5mpw zTLpc64knXX+0*tio7XFlCNV(~PA(_gXCusf1Qyr2Q&8UG$9&1*jq}s0$Pi;| zuV7U)0tzRu-o8#5YSD?tTiY9Q@P6;1cbExa@t_PAeHD^RxT=jIMq+60G=uptE%z&1 zE4n53PpFi#{eQ^B$tN&=(O&C9sbC1~v{XB;!-qDefN6A$(X1ln!}5oZ2b;;Vo|aMA8i*PtS|U42$c zGAw0b#=?x6&97HKBq|n>d*jP?V#{r(m#R|?0A*6bbmLwS<7kYwV&6(iQsrp$oLgUS z4@-_p_qW09H&NnN4SW?XpXJB)7zAy>cty970gb_~fcVkA>!r%bSKM} znu&6n3su0(9Pd92XRXVY!bg1}r+!>2cLHCTaW>A;zS!QK{y7ua;lEEUJ7&;odMD4cR17t_2W7THQZ}S{-nq6 z>kpPhmkOi%mRV315?dQT9YnH7gJPvG1y8qTVO+Ke#7Mj> z5P&}K#QEqv`1#Lo?o#8;GLADYCB3Kz>r8?2b7}2CYJ~iLAb=tG7{p9L1#o5|M_?@Y zZr*z3I?^xP5$dU!t~kk+!nj2ccLIc&PacFL2X6JHU9mvT4fyj<9jNOpmm7!#6v5My zWt4I(4K5872FJCpgionXN-$n6QuWwtG#Uo%xeVYi6RY<`VP4-G5V329@6?^6_V6xg zJwI>s-dL|x3N?vQ$Vy!p=G1RYh*5YfX+Oc-P1?{Ym~41kO&W}Nw*w;?PROVJbQil; zq??mO*D0tog_30z@#8hEOV%MT+rp1qF5^}@#F(rN*qQOn&GiR4L0`sldT07t#XB~@ z+JL5n$gsF4fooA7=lIYvxm{v<_-SQDu}$=z1}4dh8016t4PK^#1SPE9_&Su1 z`M$+@p|l-5!#i3vVOP*Y#BPCLv+z|&e7MP}q8Jh|nok9`X5*HjZx5M`So7)0vZsll zC?2Vr)H$!xe{nkxmI1MR#LRzBqWd$|2R(uVA?=MQ7XiR*QW^WyDrhQ^qv7MN>QmSE z`9Aa>W*WX9?E^mxCf3lZu1QFT4C21T_w)~CF^taR`Mtk*)O6^av&6C9PfNfy(o3bi zO}yWPTf#EQt(H?H=fC@b7;rFQi?29w$+G&{+I0>Mxe$Kxyb3G@oEXg zadEtVapx4x@+v|a5%nrTA9uU1zBF~8rL4%sMKmu%va`2n3xIwA@k8z#zi32e_j+SV zdm6}HmC&ND4FUdPI|TG)`@Q(@-Nj&S$mz`$sU|V7R3phT#R&|dZHxw&d}FS zF&3_sba!Ivv8MZ+A)5%Lv?E#i*!Hdz)toccJL_=|q)znHhF1{0&_lP)1)v)h&%&Q1 z(E2&K(1wms#FBl>B6Y~xr%ozAvaJ?KPhwnGc#H7w*wWG>>nw?LMUxmXZiT*q3_Kqz z2lk6+rLOwPF(=bfjTI5J*TjiHNH6uANhIEo7BUC3(u+o_M!#C0oNw`Khd1O7x-M9m0GFey4)5`r2kn#@<}u_K;g|QSmiJP7im0mEd~#MM2j|*2M0p(l zzwJq;6eHxutL^o`^G}kGJaX1-r^xCr7KwMN3FNwBt09mITP6^K#qdf{Ykc2SQt)J#wTI z%=U|eh*@`B?S33c;hS+o7R`EK^VcVRFo{Y__sfWnwZRzeM#LO0#sQzT;17UuYK4uK z9d?x+cH@z9$CfKFC4nW!>pj!JSUR^=@0ppNIP)lWgZP%?VXL)OMjBk4(gj=7s@MV_ z4{iY}1-=SMRWF?K<#*hJ3pg=7K$B%A{&Nr@+o2k~b0M?}%{jP2Lqj}r>V(X$ugoJS z-5#=l+DvwuW67W=H$RV4l>y1eL`#rlLe;#C89=U&y6!Y1=K5R!(m8CJ>dyb7n0h}C{|flSV6dwmLwJ1zC5(1dTO&wwT_4&FmrnV> zPx#SI%;*b();sB{*uJ72+KL(9$uQOvg7CAmHS&9&xZa*A4>aJnZxUk3xq2uhN3XZ} z7?g>QSt;P+8Dh^gfiMZkov@kF5g0wq&q7)wgg;sE=ngIyhx=eXK>_2!CBJ~NgX*w$ zosu~ma?X_xQx02{E4o05XG5WDigqrAP!~kX9zQY}zvyQLt0x_(ui+7DKEuWb8yeN! zJwBo`Nw9XlGNo9dDQ!tPnL`*RL#u8SNynQpJtnt^fWN!_^UdV;{6b6gTfib&_$ygu ze@p;$yp??(V1JKxxvDxPtS-9qMmgT^@XU?F*vo{~S(5;7;n^L}Pdw08@l6du-0I#+ zAHcu3+T&Vq3Ug-ebAorES1(u?_hU#bLXU2<@3|Rpkvk`{*r86ud`!TD{M@hAS6=&CICH-*~gUE9VAmKRU9%M`XRz2MM-j1NX&cZ)D|yf zGS^#&M504=LhWI|p$c)Wl>>DuEH2VFoe0t|(p@Vyu0jo`tvSp77^cF>FQKwYrqJGe zZyTXY!n{-J;c*oJoFdB7t(l=8uKu4L-|OHKU!MF42VVj?dE5o>Dsejk~|UagbJwste- z3pc>70(Rm2&;5FBf*v(d=41BF5YKXi*_?A8M)Exd%aX*QOX35*eS-fEWmSN9yJar9FnK|2@)W8f`&Y zO*H#TH8TUL4QhVn3z^jvc%gd{S^VzKo|luzbB`wo5JWVM8F>&rZ})SH&7!g!OE-`z z1n-4U*Lx_5kbboufE{LdSv{`+?Tj5|tC)39@F;8zwhgvG!c32cuG)U?=_0Vy%fPw+ zv1XJe#GhE_l=eZ-A_;zd&g+={j0nCPFvVfFNFaqVEiJJZ6bJod!!o`j+GLhRi|<%; zkA2kGNVS%oXWuH5JLV4YQ=Bah%5p0K&Q@O0xWdc76Xmh;N0W}Man;d^hLGZrNn2WI z`RnhP85ZT$MKS2-g+fAooJ>6SX%$o?l@$l|QfSA$^5^|lz$lmXAU$7!0LdjbZ|e3H zr1e5Z@zgvd?B0{h$1T4lU+C3sa|an&sK09TNkR2Rf%jn+I+?k?8Tp8|g5O4dk;(M} zrW1C4?3(FQXXG`_5GmM_SMOkyaZ_2C?o`o@mGDq{1uX zm~1qT!+ASHQ3Vf)kyUOt7Rk?XdNhYi1F?ZxJ5MY0OnR;qWl=3(_rC z+)2#nCj~>p9MV|uy;<3oP3kOP2XQMBk{^>2rtt3&m4Za?0e%R@5y7_u6KwzXK}dU{ z?r>9dm6clm(3yT-P$jv(Iid`zP|th6oA4yS+FwI9#!G6@sZ38#0o4z-?6$}rwLe20 zz2{W`F+k40@Yy@^V0&$)?vx>&roABXeUZ8)M|9+_5^(Nl*_tMuShP}>_iyw`dQt@{ zWVIVP`EcML@JhWKU_OF-8C`AaRxDzjo?u-49I3 zl)GVo6AS_`-wF*kfIE{`-meuYVVQeCe72Nh=hgMkg1KovSfJz%;8?hIDQPPh8ixF3Si;eXfi;TS;8pb9H2NUY|E$s{8GICy4U2W?F$+; zDSYs8StU>Xl_y_JZ7V>=S`m2^@J$9czMNw(Y*Ift$bPe%b z29{U0U>eY}SJ;szYu+uXjbbM>`sFsUqikU#jE(4MP*nY(dC_zwL42Wxb9?ONbyjMd zU|o#G>(*vBkdRscTQnk-npmt*d@eiATC3*IK+4QSdFtCBw#Y8VirqB+z{u8XzqzaM zza@={)$PeJrvN^^*AZ4zBH{6^RRGV3AG}e5HS(qQ_rDnZW|No+Xmc^ac_gN)i4^$2 zoO(J!?syUQS>9V8hA-Lodi^q32+SMk&ia}IoRv<~|Z zk&WQ8K)4&`|5U$x`3t6hGuM<32|IgkALw{_?Qbc5rZ)GdCVSldxQEk(->R|IW;zvM zGj!+ijEV0KU4fK>75Nuwrugl5yx#5c4$D)X&m6Qye}RwfqIXsPoJoU83BJC#@y4XN zp`!j^^4eHa8S&OSQkCX0mLAEDj&TGOz%oNM)k?IPcg7aRK{olVp8rCAJE7v=8HUqZ zL2|*3D#U7BVP{|U-?Pu;uVy^js7y{rw(KUC3~z5a#6n_QOJCtD+kI%TXR}>M?Bf9k zgPuDrk%295l+P1A&!ZY?cLQ`V>VKaC#o^o&cKVnQ{Qk`N5ZS=0gq{=zUSt#13Q$rk z1b&*H1*+`RrCa>iiakqviEvrMAlZ23gYK5!2H&EC*|d~&+LY`LO-piejyZAvKB(@= z+_*DJoy!2p3}34HhM`ynxBq#9nvckPd`h7YW?+@7uz^({pVK)>_jZfmcZ@9>QGxB{ z-yzM-}hTe>q1-hDh25bo&J3QMG{8bCbiW%7WTRS3VOY!Hah zZ5Ps&9)iz*gaSbR(#dWn`XKqHsBFg{ zde*FGlTR~hTN!@%1@A!AxjBl7?^4bfJESc9!}ruH=78J4`m0ZL>B`YB<#aOsyDwzx zq>>>&^otX}JU%jmC#Kein!gwyfFza*7Qz^bqIBs#oDF8pTeVQ!V_e-3{5jqa4$=>n zDqEdNHS2M#--fgGO2J1!Hb2~br4Y6+^t)!4Q4(y>?o+p#G~agKFAdSX>^+heFhj>{ zy*ogh_D72=G5|!YWOlN+xqkUH?J`ABJ=X0z&Y=LnBWoALNKtx6lJcMHprrXvBtdvN zH zbBv=N_l^_W>h@a*y}sZM)w4>qeEO_HRZT0Tw`*1($~^zEz3|cxI^fV_p9^a;mq|=^ zCz%WJfQaK44)A{e9wh=Ai_`OUrOt1lS(R8xM-5m@j|{NIWXw9UPe!&JszAj%DTk2% ztYkR{=k-_A7i#`X*kr1H3K+X)r(TG4k761@BXGy;oC4p8=@xZBdd`7HW3aB4=G;OF z6t8@63-}Ydgr^tPy6`!~Mf<9w&IW61KYPB2ioOWq7A-l5t7QaX;h+xTluG6!NVy*8 z+vGTcz)l%bxuT}H!TzPoQ9ZUy$5pk#^uEV5SmHZ0u2`pcKkntYF`okXApB?u!av9i z*%qW1#Oh!1woGB_gRuRv_XX~uX)|r3Qm^oK<0nJu5FZL(;400k6xW|>QFePHAzXuSh()zojDo5;-n<{EK52mzx`6Xl~^)sxrmgX~q#U+Vcl z(`G>x&r4MXNm(3=dYS2gRowq7PC_rvUKeUWj}h(<61OMhVlH%K$B7&q7Kb7ru{HW< zW_N+SC@jrh4FBqpn$Y1vWGIb7^QR`yUY0j_4AO95=(nx)On7GTl90ZYBViz6Db$cx zVDU?i{Bpq48uQxNf~&ms3>^Im>);af$dP%k`oLAYyLC)iVuEOLg6uE_4)$$6tvz;C?eEJ9De5_3=J!gc^U$nUo%%0S*gU7tj<_TlE#0TiEVye8SBEp|X zt}k;=tl4#NTvsIO3FciQ{&uowjVc7>+326ZT*_8CKBDR_YNChY0)y9k9YdCJ^J4ws z4DKbJQjj62=U+mGzk=?U=BbBm)(JsRbpe!w2J1HGNJ|vjmgCYSZXPkYXn0V&Ri;#fKK9gYurmXPuWw!K*g6gckgC|Cr34gGIz|bE z)H~bZzE`-B&mNj4C1r{mH>ial|_SW)LLz37#To<$yymo?Ub` zwJxGoWc%1%HacvX9$ zT0)v`Ld5jK z`-9M~P^4dCd%JdrMD`(C7g3H|hN89m@I(R{(q33)1j#)|1c3^2e-xsoH!t`B|L7X> z56tQ<=o)C^!U6lVSo-HHPb2g zRkd38EHJ?{pEFy!mKbepJKOiW<0zx^)G(c?189ZP|JITQ+R2Gl-w${`iAsShCAUEv zzl+IYhg)!DO_@oS3jVcBn7p7+8-vF?k14f}*k2xp@0DJ$glHL^Wu8)ic(=07|}?351KzrPwS z;~9v*Ot+q`|0fq80l(3^e&%df$n24lz+t)amG>qw0&#EwBn1rA3hWB)IQCYCAcDh2 zHfkPPNm%~tZil{szrS1ecBYt47voB6vVn1la%wG?kuoTiiN>JWLZH9KdW?T7k_|Px zlbZwS2?IY(mrYjDn!K!_hUjY33O;;%fz&O&pQf`g5}ES~)v1qGV61K=RZ++>}d(sQB~k#CO@enLL2{?>KJ94S{9R! zeMq+_Ru)1X#rM6w`7cv2-KnlaJNrqXKcAB$vGE+f^O3=MhvS3jk4wJSSzkSKPOwmPH`{+{&Rf0m~W)269&3;Ik-Kc#@ zvPMW=Z2q|GFql%>b3&86@FBJFIQz_ziK9k8vo)CrLG-6P939W$~g4J6N|>E(>9 z7Ci$~fi@JpUE}Shrh{ZHofd1?ZlHO4@gi{Hq$)cYu1@&@Db=nHvsu+$xqq^pkAJM0 zd^c{q@VeGI`W~#^oQcJecCyt|aMvfCS#x`=zUq564ry(W^Y`;^TS)72j6`prn<{b(@D(wpPXXmIBPvlU<1!AfDc4$B2d@71_KJ@`{mmDPLvT;d14y@h-#C~ z0w8s^MhXw`;<97tUpgdbMBs0;Sc3p&eUt6Nt&SdJ|H`=q7oVbSqnpRIk@5KMF6SX9 z?Csq1w5@|Um@wK(+U@?b&~e|B?^|yo!v`01&NDK>yw6T8X-jzzgVtL$(@qm~(m?41KEY8*R?;qODY#rlCu*p>pS|c`vtN9m1Vu43WOBb2f z1>DK7{BOdG)bMP%M`(zXKRPWgvv=gZrzIuMsWf zm;cYH5{`pLY0y3nJt`9}T_|%-?e-zda#o&UZ4mQW|5kFIqtC!*z$y;IX&AYWt2`^S z6HR4BwjAE@Hpl*nbVB3@u2r-~?Ol(x+X&}#E$025jgzakZ5lpJ=z2lfB)~1Ia(&hf{R$=e3(pFzkj}s%&h%jbJ;DN> zE0&>=Tze*c$Pf9z2@O((>(F@xOZhVGnc;O17nu-~Fk!(1!(^;@Yt#3oQ4WA!%2x5| z0j!gD5CEzJxeWy5-vkZS$-3y9xb73as2?4XQn}EgQUxUNSc;1!Hv*+&4rzz|C6XJ8 zr2gbsbR)cp>ux(2c*bJt&wDI5ee1<(np5?BBQ?#h+^y+nY7ZRXCx72lLqg_v+NF>I z5A78B)sTJYDP6x)$=a|bl?SE1aipJ92S~VdPK#>wi`$mK`%wYKNLrB-93Y>MBE`l&cplW5OC_y8>oh3^GbOSX{ed$> z7ze|q7`Q)TR{;4-^d{~Ff^R0Ca-1;WVUsCJ<5H$D zt{}crV`0<+CM-T|hOLW~WKqM}gv7L!GmW8kO4=bq4Biz94?Dz}D~d<0A_mhi@}u?~ z(uAH2pDb}dmzG&B!<=wOI_?5h_0}g zcY{%rpl6fay=qov{qW9IDC1hE2_gu4FM!`<%0b3P))R|;dp-a8nC#v%U|CMc$PtI3 zD4iy`(Gl1~A}}KNl^_`(o?%$5;MK^IZjVyK;S^1Se|AoP)qaCQAgKug_uz0kx*e`P ze|ZlmRnW8uE;E_x*%o+Q$%p66N&+?&ejYi^nH<`2<9k8^}%E!A6ej@#ku&yc( z6aK%Pe3Q&?1yKYimqYp=k7dSBfx0gybwESS?qD)(`Cr-jEj*zYye61Pl57~kjw^&zJ6+CM3xo^pda{jHl0 zJcKkm8!I|R6J+(w#rSD{pYQ+DdAFs=Az0%(y)r$kSY*aygM+6VvVRJ3DorYk))7@U z#;T>t1=2bHk&i9-cV)eC6%`jogC*oAeMBrP^8BVa&9)S+QF6a8FuXo08 z&YW}^p!2sVg2!HjV_NMjIsSO2F}gwG9ZDbPfykE?Ijco7>v04FYeBwQ+t>C82(a`F zlw_aSj_jEU%UXLSEa$lV4^2nQ{UT@{#{m5Avsn(BR`^+mP^r0!yF4lU&d_}S zY_nBBU$a-e^<$YXGyoVHrKIBR`)5@qK)k+Pf@wa(7`{fuEbN%K4IZVDwG1o>X0V!B zVNg3I&Sm0!^*{e2HzK_mI2bhU4$9E8MF)N*tEogps6nK0BXQG22Eo6C@%El5dl=MHX6m7Rou}M@G<{#w#rHg4<=(LCd77I;0oGWzJXGVieQAot@ ziiLqxQ#YN8LTDyIPz-|OJSb)d#JF?;-b4aTi!$UC)4?CE9$;{@z*-W#G-wk(GO0p9 zs;|`dOyqYR?u)}mAc~J0LKNlh`N!$fb@azf6+1JwO+Ofvk{VC9=$>)9hQLA%Y{K3>6iHAQ1&=m+>B@0hWZiA4Nctr@wwng^;y{ zKG0q+oD8DZsRrN=YeN53iomLq!opEOjo`JQa zsghuxfCrtClz=^igYwGD{Ui>f)YAmQ7-5YGr7yeeEDzUq_-YHvcsnbM5&41sb^?L;X>f5cvf9FDPZYNlb^es3GKJ&%GR3)BUs_H2bWzc zdq3O3qRWNZJYQwLTMcyljU{oo zyi(TqG!(w2FafXN%`3isHx90#9}%-3Z6)Zoj|S%S!IQ=l9V8_!NRV!%+D=E5z9IQQ z5mBzyzX;d;ttJ>q&3;zE{>vJjS?j-$jgm|%+|HZ(3DJB_(&K?-!68>3{ zzXW(*2kf@^%R^^u)uBW$-q0C390R`Ky>Ap7Zs=%)r-joA8G$6)zl=0MXYV;}X4)(r zwiwg}M|`sx5hcd*?)G+Hdx?C&AR_49Xaa&R*4qJZ`NIx&GSr^lf?!_zW8 zW6R+j(dlJ&0X-fbhf1eXD1hikVWE`UMYv{;ssz^A8qtFQYVV&$9V1u z=m6(bY_rw_o?9Nm;a(9iwR&603?)_3)l$prGW>X3QEg@qSyr42@;oCSQ2V-g`d%p3cFhYB<91um^_=(H%76Z?X_4dBRRj6 z6VI-DOG~(yH6#`-mGp*-^t)}?Fn_FGwzQJUb3I8DI(v@3ue5zhvl3&J8BHe~npVg> zf?wXLd$qMumX7CjW;Q+`*`VtzH?-1@!*z;C3Ph{Mwq1a?h{1Plim32G-p@kthW^6T z32-YvqJ|sk5FVt)%aJ3Im}!HwczflGqO9F)Fd2)h&vHRGP=*pU11gC&QP#eC27+XI zp>l+suA%#R+^f6&l(Q8Y1=Fx=&Dx?0U2sXkYw|dmwZiIGu|V-3DKK^d=1w({&-bGuYkK044*k~O7eGCIH9`OeAWTrz*Rb@9a zR@o~3gGtzrxFirebc)J3&!u&_6#92QZw5DKHiM&D4SXY;Y|TG{;N2udwHA*Va$UyJ zOFl!0-SVU09&cv2FIz!TK(o0$H1=Ez%M-nST_O3*NV_KR6 zBYE=U=#;rLFW3I=2FT z@+OmxfuhBQh9oJDcpV`00j})ogSvj0@YofRZf`^vr=GBVD|8jYC*w0GWca4VXCeK0 ze$g+%t+F=vT}5p|?wm%nex=!@l)O(?xUlTU^~(1>#?$z*+Ha*k9Phd)^&4H(!OX4} z;c}tDk)Z`V(S!`G0C25=Jsr{ks3PGif5OunVd~(v1_8I`kx9_ z*oAK!bqlXQk1|9UHpEr6Xp@aQ6kT_|95IGtpQEZ=_B`aIDh6GOA<^%4Y_KLt2XPWR zqucKuz#d-4IbO_pa-;~3zKmd0IPgHlAf9;3{aVm*b|>7MEBu(ukzedc9{Aosyp?te z>?4?v4Orb|Mr|2R+5w{Ia%r_ARcTH()cg$vi4B@n!*Sf`Qh;v6w5O&9E8{^{Q(1oq zT#eh#kc(2*t>O54sAu%7lxvw9!+8b^sa`Ol}i^10%*Scq;Gvc2V!qXk0t zDxD17H+&o1l$nnZxu)2xLi>XMZ7`dhK^guyIHw)dsO9g)lusz-?l|N+{KZbGx`S@! zjGp2^+_J1WO^8vI!wKiGPiU@$3q7K9;#Bb*Xm}pL9QSd2e(uzAfJ1~D2t;SUJ&WsV z0JLF7cKnBb=A32g`N%0~JCP#FMQKp#2-#0Cv;0S93-g~|A|>cl1>7=&3R5*5mVspx zL0z-kdJfS-KqXq@H}WcO6FWJR)1NLfTHrrQOjiMUi~&dSp|0M3McmtXb+HQX*+4w0 zL3UEq_(7V5lux9Z0pX=3g7bF)!rq;p!hA-i)p}OJF6(us$ro7Oq$BstdR8{<^~#S- z7hbe+0`W_2CFU3395EAA(Cbh@2%%zD>!n>4dj3%xv$?0*IFCJVqVc^75%dR7MUvwE zihw7#$o-Ak9ybT%Ru`S{pK)xgqet`1Dd{EztMRTH7C&NVaw)1jQ(*Mq)Lg{g4{#k4J9bEE4~Ot?&B7JQMnfZ z$9NAymQ=QT_idUH`zo2xx3wHiFkEHF{rw&1Eq+2S4F|bVzOYE6!Fk@W9BY_M+%UJz z!eW7mN3paApzPy%4UHA@bh`gj*z{uSHhI=@X6~ae$CrKOWX=BJ4|06KSV_Z2U?$Wa z6Uu0&xqz#Ybt&1SECJ)O0SqhR!T8O*L~3Yud(+cw%S-|Ol22s7za>x=LWbJv?e5P(UT-6YN1R zpx`R{Y{@_4*Q%B^<+qjr16ZYUAr0rLJ+e6ym4Vboz+i>W|!*HALPb3ikvfioF?4 zl)+eo0e5Ul$E(gv$=r8A9(*2*2#2gT->{~O)SjziS@;*Nx`mo}8~>e{RmXZ4ioPn6 z;uY2D4svVh%xBdpd&{cyp6ujQX^I>1@Dx>}jGFaW%s(H8l_3?Yw0|ZKH=vF@oIx99 z%E4Zi@sId*(VB@up}jt0NUhz$#Q+vnea=$lR>#%UMqH$9BHWtcNMsHi&?~uKNI$ZE z#d^i3u_xTKD05h-m+t_hRSe@}2i~&>Ik|X35}Q7i7w#cW1xaEr3LonZw=W^!kpzh) zk_uAC4RErgD@;GKFoju*-Qapf5%@`Cekd%8!iEFErPaqQud|h&a%YR9q{3+@cdHNz zsU%dlF2SZ}WUbGZE1mR)Lf03oxdy3#UgIu z^DuuNgxD7~qHJz3RLW;3iS1qqi_c|54>f>5LO{<#tEPo-wNDJ5j$WF7(~Jw}8nX;* z{;6qi?+=jTQO71d49E0WDBaOh3{OyxQfjH(92V7pPZ3RnRB4mw}ZwI zG6=7lyL@LyET5ne6PU!zfj^R7b7(L)^p}fs_gPWu_ZWMyej0n(oe%u4)kON5GD8Bk>etq^t{fyaebb5vxF zS+g|J zXB*93k6~m{C=2JJ0u5kF!2%CfXnQIK>cjl{gSxL{5bM;CbeTQ+t??9Ej7W8SL?<(x zV;p%I?zV~6itCV7kGIdtRLsyM()SNdJN%~!`&q}FMLa#1FqETCj>Y4Fego0*LP594 zup;Ys{}n?o0M#bw-errtnHh~;MNsD|;1;Xsq*HzTZ85nz^l|xuSZ+o-#}i%=h_i>& z5_Q%;d#E_wycU~oY#Gmu#I=*J4&T(y%yf&^#$p7Kep%hlaYA*B;StT5Fv;??%AFM5 zJEjQ!J+pq>7F3MxCyOEAZR2HtPxUz8f&n5c-%#p^C+$|S31rXO+k+YkYYH&@pG{GX z>7nT;s5<29`B(JLb%QgP-!OPvh~l0cR?%TVz%ZceqxL~_W(($jO8Nc*bnIONK9iex zSn#2%Tm+9zZoaraA(C$E<}dK){Se4GA(2@E3j$6u``sD{AFstXmmZkcPxLC3xm@AW zKOr-B$UO1`gO6@?QNXXrT83XcVGR6#0KwkeRU|o1A-O!JE#D z%pFI_Z`h#QL;CF3>Rf=pc5JDe^WH=GH@uS$uH$}SAeb#;u?J6&I*u>CP2egVGsL68 z6*y|q*N5oB#VQVAK~F&)&dKaumIG0Zl~YGCnn%HddRv<)KvxKVEGc}@aMUBgy8Hk6 zznk;rM$J?c7|_&&Eu-M?$LqEHv6?h{4FT7vxP65JN^$0Ph#j#ldScJIDKW_C1LJzt zUhlWMhUK#q3gWCbw|BQ_jzmnP4cv#K*XwpC|6H75)Fe&T(TJ!_XK@su)6%~Xd7lz6 zRXhfBiIf#AvP+CM>V$>TY>;uC#fC|-Vgsu$$oR}e*+F^LH)dTs3!n&15uioX5*qcR zK0w<|<4n2|6|Gg@GKTI1AV{&2MQpB!f&CVi0eNVV89j0tqXGXpS|>2vnQ@=ODDUUj z=dVJ|Y80MXdV|o0pm}{Fqu?IOSUe4|ZczKN#u+bW)kiQ7;q2_f%>ShY) zL|pvL(zm%mWT-ghWW-jfZRpo;ItqsIXm`^Nje;H3Q^luYS+B-mSDCxlf2MU{^MxT` z=dut@y)s-D0_alR)LbS4Ii0BId;)r8UW03J+Y-}|%6EET-?!(OwFWnoe?zo3!(!Yw zZI{`(k&$wCgUS!vox<;e9fb76*?mx%Xqstw`T`g#v+&8_zka%oZr$D^IZ36YSMnHk zgxEO)>R9Sga=%>qdKJ@ z{(_&YS-o_CF8iJ-IiBP97{Pvr4xm$AT?)^`ryKS0>C&h4SJGQ7kl`2a;2U(Ao$8wm zgL%%&fMZVD;;g1>00{-3qdi5$I zL>A4fn5r`61Q4!F+iEbW1&URs4%%^B8;bv$7H{adjsZCN^LhO$!j+LMdbkAYYe1l| zS#b^I+#~CmX8-JDL4CA>H`{=o-hc72zsjGd+RgTV?EP-0I2rOTa&*(QTBe(+1nJ9q zV0r)| zF#XKCe;Z+Cm*@m$X9*}*qi1U!9gZhPBdFf5M1-D@T2kjo$=pXB4-1r+_7uD9Nbx|{ zz*81p$C9v2&&);5hTQIN$(%`!D8;>!BJcX_P=m|o?SYG%p57?vy`BC?@(A3mZ(VY? zwh~(sBaAdwlr{|uMUL1TuwALRFS?Bh;*Wr7Xs>UdWC7Hne6D?0+TDvS<2fl90z9|b zUo5dPy&oXd7Pktx0(iT=Pjy}~Ku+8`2L1y}2K#^6{R2!DD%9Q=5*0k+hfU&(&EcVRP8!kU z^+gtjwxiN>f4oF{oC+%fOC5u_hi8CeAMhRu9>5-t<@Pr|fuQ2i7Y0BNGWv1aW3eem zSS#u1z776Y6*41=Q0dIBR*;C3USGpuDZPCr%b0h)bnT(81$B(O8b@BQ4bo9)ZKwH} zzFcUT`i*{>)?5Jx;BXKXgGN8JEDF3kefhL}8#NBQc!K(tLkJZ85itn1h>n)IKuqza zj{6;&>m41DJQE&)gb_nII1e~wxwHqAtewT^tAi~Ff!73#v^@$;3npbstIn8lnBb$p zG?fF0Koj!(79+C#ljL+wA1R>L)}(M($mr+E75Uj7L^j}J#HR}1-YhY44o!VVGR~oJ z9okI|{DC?cK;jqiT2>wL-6X~^N|nObsX*ISut?fjA84M-wb7k7gCR)< z%!qCl>F-9B@z*xrVeX3g5Mo_xb`6SYZ*C-i=O}W-dgyI@!bJds%CE?BYl_HONEiFt zmkcl>3eBDbhQiZG+h~VW%y)_Pp3Kr{D}=}B1Wj~^jKjH)qF6sUz*`8BlPR4Pwvc>W zLJkXB9>t>`r8-xH$Tu#-G7hM%OFd1#rHdiZIN53;ab>U>Sgi6uB*^mpbdOVAs?~N_ zwP*%(8Uu2X{ViZvAa9K1`yZB`wZyB!S#@{sSBYdcspw3b;EWd)1ypq;y>lWmJBV5z zWZy4M5gVjRg|pDU`l&?20e^$Ct`{y_xdJ)+*S2k*H! zjQ(h6mUxo5mKvxAKNy=FSggI<}1;HsTKbq`tE+%A|NmOx5l%ux*6pysy4JmY^hhGc_#cvsm7;C9)DjO~>a;$Q-jt4fvq{*JUX-rOiv zL<1eG9Q>2&hGt7AMYI~MXSnvK#sj!uNP9D|Bj zeXf8VtPHCY?$hQL@Gg{&EH1jXw14j#x7}3;9Z(CYGZONB20X2U=YwK?((v56wQW|uV=L0OSjLe z&QkPAqv>M6el{}qg%^|GZvb2TjLU3@DvdKCi|zRuJJ^C$obIudUZ7ia*!CJ81#+;+ zdmX{&P>x*J-cm@%dCz}&J!sTwsWmSds$!7*9;=LklhVZf%?s6&@Bo0x7b1X;U8u1c zHSKM8vS%9`uv{_!dt&|#bLaV0?x-?fDEwZz(Ps36N7WGD? zWvreU-W`NgZNf3@^8ycsfyu{T%c21N7tHXWX^A^aUMXDvbowy8>g2l=e$(yKr*{zX zJBrmYOo*<(ICJBpx^jEn*&Y6oQ-6NbE44<+Ci(8xZYUJIytdoH@O$49rsk99&>Nl; zH78!G*N8eA$o;nTf@m|nhb^#Yvg=E`yagrb>pnCP5mf>Q@Ad6&@Ubk(#Ff;?TL!rx zHE4AZMiSLky-%_Pr*Z60*+K#a`J^Gek{u&l7IT=UkddbC5J<%XF29XWW}2&2hKKw( zO;oAfIE+mU(EaUup?9zNrWFTikwu+6G-cnBuu<(?b;22qJUN}wP zXww-4(yiQD%a;yvTY+P&_JetuuP$~bzUC)djTn+AN#&|`*1+&3{UBDp>EcTQyiFV7 zj70T;dAo=6&Gba6+0)RHb@3GH6K<&8^-nd!QsEfx=gLTNjj<3T-n874Wi#mR3o6wA z4!p+N{$55wkZ$<)`Ze1Nki5Nz7tT0PBPTpr29Hg(}v7&L3T*uk?qj@!{KjXZj*SFT!vhpkXn5xqL5u8)dJYXK!$9XL( zjIJnK6><J&);jV^sCEbD&Wt4?5oTg z8CnnCa^vVBn_x~cPt*9+2*hK1Cu8xHzA4+_e7ejF&?RXjwpobiWpC?@y_WiTng9r@ z42i~tn~&9$lmD(k0Z2eNB@HZ4>F|nzEh@->I zuqMNVP{}TRVuk=es2dOUYBW`{=J!}U%YvY1Np?z`3s^aK$n5uEhpqwrug=`Tc+?JH zE&Vd}mimPfq0b9MUX*-ktw$Il^T`9q*0kGve|-^gOi`0_F?JjabZ3Z#|gDYG|fiVSKnrgXs~MW zO`Pvhd%^#G8PpYIgvcfikH)y~*5+(afkN2PL^@42E@-OQ{2-y64q_hA=qkcFRHel znZiYEN8>ZguLQ#T=;Pm0D4RhVG|pr;2`^fJbH*i!Op)EkxK}bU^MU)m34?#Qn4)f}{kQGjFveBP!r`Uu z8|(|XKk&V8Edb{uhClt5D z>Z(2qpp!Hs{5hAh`)5#AYBsDRPfu!hU}DSkhssEn~-SHPT)A;=^c zyF#3eO!km0idw?cLB1i{w2B>TeZRhGSI;lTVIUn`+2#gF%OGY@o6ex6t@kcbPx z6Ui!7P+;F#?}j&X(Yp-%X?!;P^_5{PDM}ELadYv1U4(q{fS^x{m}YuQk6Wl?8(4&r zd>}!BO-WLY{ZN&^rW+vgSggF}>PH=OtzQk~br%z$cJlin1y--+}dQ zi^Z~uD?0Vp5LyHf^ns3u>pumXymUJt>g{FXTjp8RG#d*r@jS$v6oJ}$0Lbu(Cu5Qv zhs0jD4gaU)&?su3U7HC(<;r4uw-sEOCQDfZnvn-S(THW>J0(f!wvsC@mbwZmg74xlLvhN9H04t`a(I ztMxn2l6j04E_RFU%^AlIrAY(#*0a-`mVjCXr%W-PuU2AOSjj(nMibxD%SF@|B99U| zc+KA0kewH|CWR<976;8K3@D5KY8R+s20xz2;cw6Y=D~w?n%Y+8;VJUqUZZHa;gfJT z*#XAFp!neCg6j$bh>p5y0NB8|&`oN7Vf4xN4Tiwy*zB)L6hEe0H|m&L(jA+Tp#c*% zlX~*;%*>_q+Vk(l9D2FjOqL|{XB|IIpAwV`{lX$5ETG63+=KZhG#24BC;LC<%be?DugmYsXwi)&csWg(0xjdIJg|V`EPcw zf;W8}y`>z6B#V70#(~pAB7+gLZ}i6P)=WcGa&0(C``3dfa9sMwIBqei5dm?5bcM#` zd7SttCQ!uVz-oXCaq_C8^8$)353|&YDbh9lZ%XxumA_kFNr`{=(BRZ)c%%n(ob3IF zwGqrD&cT`mls&)Rekn7lJ~>;eu#DlBV%1O*A){faA>CBW_8ms}q@Rh!c|cTgju5PO z+U!6n8w1KCGWK>l4ca zHK|$DFqK}b_2HCiRv87wiLv&KmYmPeO9ciNj58q?h^Klos7Ecb(*|wMhA8DSaGh$u zXi2FlZFc7DQJv6#E2{1-9(^ZMU#yl7afF}khIO#kCR3d7^@F~3oIK*v9t3$WlA=Fe z4Gr%~&sA2=wA8fPN7nQXdm>l34}jW4GaY80G+23%AqhJ3-#(yVGq)h8W9o!RwZOF- zvGqi~|DD$pe}?p+rQN9X zm{y8aq_O|h$HwfESJi)rY3MrsVEjd(ScG#Si?$)#QpX2=q)g!uP*tm(W5U+>*V)3S z3Jx9dL76hesAz^K!`~;lj5s5=!j*?hQuUgdRM_-#B~oyAU*jOOdm>bsB{%3isBI2U z%#QgJWdR&z8~{N;zQ6Z1JanT~tJOZ@i1n|95Si3)D+Y^dP%7}08qFoH91|393NLno zeQAU_qMTeFs!cmV-&X#vE${Ln6hsj&rc{nL;pum}lpPqUnE-At_uOoQxXvd8yH~0k*ErXiEXt%5Cy74lhNm38#~<#DHqcO#s`F%|*0k?3#cx4@ir62|D8N zWqTT#n8uhpTAg2!p}Qua}i=RJjCF{j4)%q-W(U%s*;#;%>*Y; z)7yJ%J)mFxj%Lgi9Lg{~pRf@!vL_>EIC}*mPMDiLHF04_@pNegyn61H4>V+pL`h!L zFNG;BZsxgEPF_?yW#PQXTN`(Z|Jkj{TW;Ycg8Fa;eRZmIaV%i~(Vc69-;|y3hu-0& zY{8=Ms^i5}V!kfWs-~P~1esSnO=m|>2eDP+O}Bt5x3QUSO-SzCr>Ahi0lI^=Eu=zx zjCf&Kcu1-DzCrb2NFR`*cKQr&9kh0tfL<{UAs+pfqbsUwnz&@f(l0mDm=5VoU8qGA zsQ}Tjcy>70@kvyCPWi0fa(n=k%@P$IwXt%rnTy86t?}V}D&k&f?Rng6h^?k>Zx7%Q zHI@*>byb#pkj}|sbl=BuyCC|1<|>abGw4*PM?gW$d93v<#F-*2@Wny;Pe4!2D2B>7 zT?U0(mPA$9-!$@hYP&X$uf3I|-t(0x)b*SVwcskrS-qPLs1I==m~2S6dmx*J=RzEz z6Bz65FWibaO`(~c!f95fc5NOh=n_5kezG()@rqc5&SGnu?=O+Ro8Yb(+lrI6MO6|e zfXW9H=~a1&2lK-!kyuG(y->;ozyrA&|K>7Y* zd9_|>>dAa?!ltjTe_e*Ybjuz8D6sHYbfL=s>x-JeYH9=5zTRg@0NLT1s?GI=bnu3U zWKq}yYl}#bLwfLnhGS~iU2eUgDZv3CMU(U0A&R&)9BZ`=q2--2c%k0 z`4;YUU_p!jT~=%Wwr2aIp3bb`U~iaM~vl^K>>crUvBx*?HwH)dnn*i1Kd@EgUnIQ*2b_wPh~@BfMF!IlIt@d zCPiExJAS-Ib*Cv`0}UD!9!?v^6F(vhi)==RO9(m31rTs~oHSWG_^QyC9cdB$ZuE88 zPoJGoDS_J125PzvirP4>E`{YiqlP?Q6TZyP$(FC6X?5#&6iWIX->&|TEu4A3Zb4T) zPMkW%GyXCa3@>t=Jwp^78Q3g3aNV@z>IRqWWwyuTrR`3Lk%P}(bggl)`>iJsu7ZrSdDN?yqI-UTA@H(k|3PDCj=MyOGd`|Cn!@3AnHAcO|kcBP?!y zv{Rq@z-H=vfJFAlE73b;O&GuyMJ>>7>G%?Yj!RKTQ*YB&maw;IRfi4cP&kGyixG(u zq?<)xNd{!2ehs6&Kg4Z=RHo}hTLb7tv0m&rUvB+#z#-IqO87EcS*wAKo~A^efZ*VS zTbR=mt?$!A%R@qw{=f-gepL}et|Arsa_t;>`p}|f8gi!JzUpKOklv2Wl0v9kXAmjV z7@ASxM{y7&-D|}{@2qwIi_^U4$vjR+F`^izCTqXlN+k>)VRxA|Ge;K{aAWIMRw==^ zl1%C9hwM|vt+W*sI{@wGOIAt^wcPUGNGLgEje%hH@U`{<_dVt*`a;$Ei|JXs@b>Jl zQ~Q^`snj^>O8ex2_&3A-8Pq$H(ToWz!r!9F5OmRMB=wLkXBi)Op}8okm!9kwRwTAD z^PceKF^gwDh_-FoAAmFcbKYDrOJTQs?jyH+N+DJL+ujx2l}ZVokeq@0ak070S)x&c z=o_$YdKk)(haf1Ln=Fz5L5>|;s`XA;6%1sK~ct=+o@U})pP9?dIE!#7}p-5!Txvw}x=IZ&8 zdKk!_gDF#Aaxp!~gTlPOU=PricPSmH-0U0Xd4#Y$I3CH~c@G&H+y6v{ttK?Q3)wVZ z0hk2di!+G;NuqD!CM#ht5dEZ#Bv3`jYMYF>DBlr)L{fW^aZ2&jDlu1-<~{XxO@=cZ z8=Qy+mv6`%$V3b4$=cn%ULJ7#QGy`tF!y$uyT-(W@~2q(B=QLeB`K$364GcPAySih zkGgRHEsOmfUl*`)$OD^jrSTZS%$)}S2t-ws7V&dPP627k&3=*|03wfcjfvMcgs{Rj z+PQa_XYe)8k-ty3Wml9d$fDL?1oGJvlRZWo|G+mLonBfC64cIJLMZv{z9uD=-Cki_5&N<`m$znKxD7-P(q;K>b8AcCF&Q zULm8GWr5b#kk&hfxPr@jkdpoS^H~iqDBG0`MpU}BPeRF^aIn$Mk^bq7G!F*Hj<|1CJ`_I z7Rmtk0YI76tumbNXMVa8(003Uv|QOwVR9nOCu#coqJr>s7l&!mSn)O=hhdl(ec+SO z_s%Ka;y)7?{&+vz93h#g(?KEdFtd)d84|2~gSskD7ThQuhje2HESFJ|W>9>C!Ui0I z3!cZGN;J^-l?YbAJM<;z62<;m?1Lgci0Tlc=AF39HH#(^^)79w0t7mG$D;cj6Ws2} zjTGrgTjI1GZLK$f=uzxv9KgJpa-q`@7F;=L%I zeb!d;czi~2B1M}JqCI@R^)#Hr^UB`lbCxVQ1W*hS0EVanS^Wm|(AQ&qbhK+aG}Y}% zurnn!u7knke_&}13LNt@ko4CnbVb7PrJq(vmE4?layUQk%!Xr7 zeO>5@n#@mG4G(LB$-w%Q(1LI~lz9(mK{RVv+FV_CIlO`DppF6z*(toau zSSw;=u0h1|b(1lcZC{Qw&{Rgavi*c1%IQsNa{chcgC-VdAILmb;<+i8{<7PX1gv^x zJs>C|(byl9HU;LQL~F*R$IPJKwN_nVfCMLY2xOL`g+eI41YQxGbJnpLR!G) z^{0(!|D8SeVI4eA#S=Zj3)LW0F>*L;ZF;74@RnOC631sb&Ac(>n#yQeKmJvTDE&`} zMZN;7PQ9T;X06YJyAsXJFlP$|BxNX&zf3IY@Gwj5DAZ0S9r<}5BcCs`)aV|)FkeRx zhp6+IXgA)66{~_2BZzJ>ENvbrPAp($z=3t|5fDj!^VJCV!xl8$&0>J}<=vhU9LTMV z^fpniO7KqA`~uE0#mK0Mtyy?RjZAPWKZ@8*JE*Ro zwV&z*{fn!%;@_fST_N2#j9%+%6s2czq((ul?2?`fWKmm8uF$NrgxiDpHSln|E)m#6 z(lEhJc}?hh(5iO_$Z_7l*wrnMWnAxilYdjn?tEOrmA>rlNuz41l@ykYfV$(KZp~E1 zNwL7Or}Rv)c`M;#B+;MuiQ)gFRtbNXhy6)`U*C#oC z(LNUL7fb&qsK2xrs~M>cE4itDwbkCS(j0AYDRO_%#0k8D$R-KobJaVzZC=Tk0hMOP z^^2`zkF9tlu_|I&1cy2_+UOd>{z$@9_r0-FV3K*VlTxm`GJ48Z;B-e+f9BXoxORt} zU!r#VEF8r~noli8!s5t56T=oY5Eja7aog;Z_?QPjJU&O+_ySIn*OI;ko`yyn;XA!k zTs3%9$J!LLCOZBiq+bT`RYA8-bqxhAHI+lWzqDF>FRA@0TO#^(n#jwP(n6VI2u&W* z=c(9vXDJ-GOoON$bkEm5+r66CHd^CdL@MeNIl|SIyLcK+d13522!e8j21*;JwJ?%# z@ryWWaBPfNDw1`?Y)dSJmH->OzphyHVV57_r+)AUWZCvs8h7m_ueJ;d0#uFeH{%~J z0vDG>rLgU#*-E-?vZ%Q+iSE&R6JqMl7ch#1^?yqhAzl#b>Y;Xh=nkJgCw<44fqVPu z&A%(&(lWjq(n!1Dq3U0o4=OCL6LBLImpn0s#zg~IMr7}j?CFj=3Q@3Yp^o0#ekx3F zww=fOEBl`^wtHQ?bu-c%Ib`qER)s1k8`hKW0!8&|!jZ%;n9W+RuTqi}N`>OjV2{^R zJDTMsTKt2ayGva^hNEs}mS9`85WE1v`xqaf74nh~t@=}!eTneBl}pxjG%-;E4v)_Z z{HDE5iB`Z~U(Y74pLau<;sV}I9^iV@mr(+p#?NwB6;Lr>vMvMbMXqitJX)yb`KH|N zEvz8dzq0Y(Fp;>C3X_Tr=gj%pOcCEdX$l*Phk+&#{sPMpN$QsSMQi`Cqf_oWy;5ki zPP<wZLC6F-QF5o&8x`CE1tO5L%{<-`54d@WeYkILd`8Q|3Zs0fgV(OB}^b>Z6% zxc6VrzSiIl3BkX)hr;`tzl8=NG0<0^vsjQTLm>*uj~Ci81K5fuQEzLe)9Ku8Q$WC5 z_u=`$d*!oTvRT(UjCkgp^GEfn1>KzWR0Ns+>CSfIR0vS+5A*Q+A_!x(NN6xC#UHBf z@B&W~^2xG0t79%0f%^9x)iCS(Y5`te>%DMIl$-bu332MK18dujWcFPvC9h0d-vAu7 zC&F+xVbTxzi}IWNHiKq^=cD7$6J7_|pT_KU+2_04O<{p-U?^;?@pd?Th>Nz7o2c?l zy3M*}UY%526E5~C90V;*;cP?s3~S;sZm#FhtcYQWg@u}$(1)+Vlrf8UdiUA)wW_^i zo`jY-0%Yiz9daglHLNalPuTjYJ)k<%>Kuw{tiQssq)A2u#d`vwryU@BQ?CHjxJ}6Y zMLQJ13?~zPal4l0gVF*fZ79l_YU~84?B)?t#7yY2xw{9TwPWe1z12iK@o_$r3aSqv z_F4A8!Sxg&RCxl8T-3k*0xi!QZPmhRkrYJQ#d{{JH?I=o?DX>E0}jYtV1c99BYBonvyZsaqYabv~WP zI=!6k-_ATKhQV_{ey$C8%}dP-6^~#$v?HvftmG;OJ+|3pe$rL_l2e6A?dz+H_hU8)5Vz&;&=4p|t`Iz_vw z|Eq{8&wjf2YHx47;gx{&#F<}SwpHQa+R}InPPqg_1}B7}??0E=H|*AI_PuY$Adr0r-TyQ208)J^hf` zpQgc307IQBaP!c=C+Iz7yc`?s4>?Z>+3?e!#K7kZ-MqH zE`mS8C-TDt0ZwmO^=f7C1L+{W{E>GU%y5-1O)R0CUf<`iU!h(KvmkDNZfBv0!IV|du(zcd8=l1}H8nf;b6n|k&F^WAu%=M|)I(uvl`*^B*?j)dc_Hss>JOCQYEtXUP2TY=Xc#gSipQQJi2sW(hC5 z$tn{W_~jjmOgVBQezU7acJD|p#q6#GWT4Uis$4K?>^SEAv7G?y!Z(yULMTK$A)$qX z7TIF$3UW6e=Bm| zp}KPmWxXVtqp>gE30bJfLeoC(H+I{`#6A)zLstl-W9iq)loeZD4-g;WPW6UQ8>cU# z=2Lek0qO$4ffrvY5op>_6$qLR)iV5rYQcs105;{RhEbVP`2JSm^U{)tw3^UeU6Ifj zbk0HaqEonH!-Ia-Wp57uR%_P(k;!aDi`b|_g61&r>aU?iW~@L=r52~?(n3GsgjsXC zGWEu^yo0f5_yA&lo?LcS@RLmPju*2ks8F#o93IdAXAzTvS**aT%-y}K7?X>JoT{|g zWY2VlQC<)|1Uf66%O7bggzg6>B-_<1yQ2UOUa3;FXp%GH`Iew^%4o;oFPg+~gI_^I=zsN)5k^&j$b1fF-;(F%kdb=g7JI=K491d< zI+2-^)i2*FHOOuufC_UF#{kw_48Hx852kp%iqWuI%tDdoD4z zB}VP~i)ho`j(gfwd2HK`Z836BT(O0?S$pLplBh_^)ifO!CiyzFE#uU&@YmBS`-SV3 z?+-4AhuMB3BCd&~kKWN*W@;OkTxK7OUpi_0#HKkdFndjns@Va$LiaE83U9B%H<Wy7gvgl<^NQ80({AUsEG^jDM*0wPZVy__t=K zbJYqEfpZL?>2N`d(#ffCn7X*H#?{#!1$~bOotX$*GH$`jQV$Z9>w7eEe?act4|0YDR$;K~V)d{kP?g+S9zp+=W_1c z55Z@xqgXj7*KM14JBdJ>#5(}jUIoxUc_NEm;jVLBjG$i1;<&dAhogGt8wBpKr^cL6 zt?b*n1gS(O;=HNXCa)ZDdq9gk!>9OhP8-ZpRF_B&*fxB>|EHh~rHMSntpM*v-2BB+ z`CrMB$2bQPbx7utSCU(B!C9W)Bz;YWFeJ=Lcp>=WYVpdTmMoCuF=6dD7Ak|iY(LtH zp$5AVu6D+fJAVhbt~DOauO2QV;Qh=u3w>>hZ2uSYi@9ItlrW^!^&K7bDfxIiF<%4H zxeVrAS&O%Vgu{o0U4Dwu23RgHU6)O7)bNsH=o(2=5Io}+Lz&?O_d@O;1MgH}Id&1; zJF0=#l>xFTdK_OmPp@vrbC(N&ufv|3#7eaxE}z&-OGNu>056ljZXy^4uTC@V3k^ow zWH+mb6Ajr;6V9~L*B_7qHFjy(>+Sb436z7c&s0fc=3TFcm4;xyrvn#@qk`oEU&8)+ zEd`)P?|q84q6}U7%;Jv=biW2mvX-awlHPnsp#GT!3OX%i#xrhJoOSDPt$$`z^M$wv zTJ0=DV1jf)CWX!@xQ>ONlwwQ-ZqH{praMJIlQ*Ys*Dp9=CH^>)5!{iVMqp;vEdRIV z;ishoPwhA8)qR?=QrfL2(^@_%YuUzBiq1>$B6{W5=w;GQHAU&E9bjcM5Bh?%1|~(H zFL|n6LtHe#{KS1p*LSb`<%&M>-c6GbtGZ7iev7z>CBIuk#T3EoQQ{&nK^H$uaJBszw|?)mL0`xrHn@`@;TnjF9IC=ZpQIVA?pd^`%{3yf%duttruTXg zyQv8$T--ZvKtBphddN;dhLINCsN#|KK`dA8L!%u?`g0&n{lmJi4U@2|8%B;Z973*N=s_!TfnJsI0w%RfF{XwvA{hz+PNH9?>nEBOro?W< zaN|TfD2%(%J9}=2MA%+O103^Y~MoR{1ioVh) z&G09H7Nbl1Dfxd^;oFSy`(B+ciX8GYqb283q6;L^%MBo^Vn-7So+v+#vA5yg5-TXf z9;`t=ghp$SOT4`oaBTgm8J@s`xU3M5^AWCr$bXn4;khan}&L+nWI{3rgi8M#IByd4`{5)t$7@_?`lWbAhl|%z36deqU``P z6Xw1$9~WHi1;M)gd6_97gaWWkGt_jYT8N?LmW@N!Nw#w7%aZ!YtqX6b%2L<{#Tms}=JNuiSDgOcFLt{=$dRUeT<<2gD8vB5@o!Sz$rlsUPh(J8#Iy78%(m%4}?*O&Kt*TNLH?K2luwRa9lqE?^s8)<-XB#X$M9aE= z^Qjfv6@j3zV*QAMPP0Lu?BOy$l4Zwq5PpVf4;IQlLB<6I%~%fIZ|9qEXe+`Q*KSPU zoED`KDkW}g{fJ5Cxrz;EVtHj-RhT&9%IwUKXvlbnt-%qiskAT{yn#F}!o*tHwxyoi z63fk%j`GOR^ZKB988czT^NBztw*0z{^G8cwM7Kj9q8|Ee5|aDXJm|Z`nA)Fm+##;I z`rM2ySO7M|#Jr!tvby1X7oY8F?Xwd#$1+$(WObKT8`O&*d2QKqRD0EJAp`u=yyMtN zqJBvd`8`ZsO#xvzlO<=9Y@-ij9hGf>jw|w4o^h?FMAfbHPdpYu!D`8mJ@^Oxrv8IU z3Gzn)(8jqu(_4K)vK8#ap1biM8N1pr%ox08g`Y3Z`%0=npg1lU9d= zaSK+g^$0o@eP{Je3@F-%eD`!`UF9V75bF9B%Ay~&s*+y?7xttD4->dGTo55;AC#$3 z=qtC%-^?pw1Wzr>*Xco<(u`V`V5HK6=*UxBX+_dp(pIwWF)eUl+2x<_;D+F?2Z)V) z(LTtw4-LaOfpS>7l-Y&YeQX0JqxYN3GH1<`NK;x~$Kh;hMHiZA=gqImF;$@%H)+mg zw550Nep(CCu|~Iw8T zpZWV#vdh!zwjq~Vfy!^rw~NdNE1%!h-5Gd5I@b_50&8^ITu&EM{B3PCod(EumshhA zg}Lbn-vgT&N>K&r@%fKhrCdHKWNW}|n*rTO{V+3HyJUq>1++M(yAL70-U4(2x$}lUk7gu-(1fsecCI_gd6rX{$X5*pqW8AMe#|MZfu z1kq9lSH1hC?{-nd#OxqM6qo6;GQ9TlV{0|+_pb_k^C*df&=6KJp`>0SMmF(<{ltSSKy_Kd%)r)>IoqO|oC~VqC|8L)s#jJVJG%T0q9- zS>_HX4zSmV9Ml)JInXS)&D97vgX(pB`n?!tP z!B1GoA9&lrSV`}#Df8rRFw6X5h`k_nh5iK$NrTicSEck5G&TS*zM#AwvsICf)0AO5 zYrqEq&jKSk5C+Mtf`$`rH-k0FIDsTt)I<|^`s7yG)GeB-bur4QnzF0QvB@qeX5G?Q zy!;iw0QRz6Ccz051OwioYw-P=fAPSKh#;$LFPOXAZJ_}NXAPEIEP-yC6k4W$bu=+K zLXyi?_;hAdND)w3#c4R!)xy@%ndty58M+ZQ!w!;j?x(~54Hm#ciU=-Bbgu%!l~Tz6snU(_J(m=MNuVrArbX)wGYMc{Btgfx;PEuR_)<@^+CKBR1+TEzLoymFNr-sufPYQNG=S1iY z0>DHfe$U=La!ZId+aut4eKRv(4z%N-{Ui?g{wojfeNYD;Dm*%LD$IxEio_P9nV`n? z%p);uY%X)OcKP(~F(Fvws4F2H_ZS$LW!nTc;Z%3fOxtw>$1x~sQW+6;6FGkfJJV1z zHIZjuL0Z=9V8_b5{5TUDmOqeFklAeOmt!gzLbCLz6FTek@~E8e2>!}Yd2Y))IzJnM z7`%?FPPfRdAlHF_wz+U6~(yagjvlQzv_`$FRCQ>coedD#x389L$oD zGdco?kxz%0i(`}%Jmm=V5+Iv{UMGIkkFeeO1jb+8W177Lg}hwzgqtH`K@bUk2JiPS z(a+3Q)aJM70<=i*8WYbOXG_05Ey3lu!a#-{E=wGBf14tQ%j^<^%~#}-3TUVMUoI&h zRX{6@9Yned}^l#k69M|oY!nq@yv6zFSH-oZ8CrOHo(0pJ8#zmes{)`VeZ*Yrzz`hZvd8J8D z0rRfuu@<1RxR}2`PgSI5;`N9Ke8OMTo}b$wJk`YeTjNlPed>wy%(cNMlM-4UN?L&s z_B!S%Ka|2cyNN^UF2y3b_7s552>hR-??i$#4Fp;1M4oPRw7Sh4{ciA$nld1$mq5Vw z5KDT8^@-SD7)|9vr!Edtky$8%zUDN z_Uji$zQ74!K9oq_R;wCp%aJfqO2AxuM~Mn<^l&@P6wu49C;=AZ{LUR?aUaJWhYr6UM$sJMh+ciUhb zSTaR}&@2mASaNdl-rHy8NjSU^v{2GW5X-*1U{E8EB7GkI)cf^n?YWfO<55Wj#(QSj zl}PV0{SPkRMV0XCV;Fh;bCfx|XvzzTxm`f4=@a zc<8(7iu|IJ#DM=xryu>LMr)S@X=FYu%B~^STK)WHUPa&WFhH{a8X_7b1~wF(-?(wm z8CmwODTR(w?+Xv;9yRYB;18I9j$DA=sCCeH`6!2-gede|u9Ow??f*t{?3&#|fDN4n zysfR*xr1VeY{XSb*y~s=M@DCS;(=0V>c@>(RID_0jqI#{4(0|$BTP%y%jbc8B`&pfR%N~*hKR8xI;49-3w>8f{_h?-+(J2LUM88KSX zS15TL^eB@}c>@K;e9%^;evU;9W89rB6_j-VO;t?D01nO1b9rDGdDk!XXC1QVK^(da z4xf|l$^uGyjZ52oU9e3n)h*hIF_mZd_=*9bsEbi1Xnneh{1;5CoYyD0B|d^+lYR`C z-yVv%glu5Bi|zk!bAMuu&Gb0)J>kIMSIIr4w{ByaCV{}RuUq-pyJN+#;tqb{B2p-HJ1@vm89AkimATeaVmY1x^iyVIX zVLhYk!-hm-jR(T8l(0tjrQjWe$O(BUGL+`SHfU!JKR~C%vZD~QJZ%xbLrFvNw5Wne z&+jb>nE}QM$}64%hI}s^Bz-$Z6@Y|r-BT4`@5mM+(f=GK^YB)X&2EssxXhKUPr!6! zFAn*|U$CacNUOQl&`fNdScjx4k>&St;Q_>~2;6f9>X5<-PEtB3j_^Tp&izNImGL5>1c{Dbm5@^Zm<{sd;)6=CO zBnw~a zJincJhP@eLFGYpM*}qs2Q&Y)*A}fI#yeLj@bdPLDAZhq2fVsx-EZ1!LYoB-*yLanu z$QQBJlF32;MW3|-AaZFv?8}w>hlVavPuOR10^!LJAg<#gWWV(!laJPJ!Ncs6ntf_l z*`%!t(9~{b=z_v=aiC3lNHw0Ee9d~-RELIM+mke&X5hkhd&LzjdF;> zC`@M+l8Oo)Nf+5G#+kByX4?)Jv1Iz$qiI4}*Ie28zTe7>mOqkzz*A~plAM6&v0#~# zvbRvmxHtgtSV-=ie`~S`Z{`^J0srWL5P;nvC#Z{uhYbx5YtV~!67V|k(Z|x|ID-OT zr`<`8!Yi>2U8_YHGnk6@*R}TPJNn0#Y%$uY^$%%;%XS;lZEXszTd-DdA)kv-# zvRdHi)t14Cf#_QUl|BWj2ONGnL=V04=ThVQ_x2{>ZFYSLo#%8%nYWa7j*bZKK%!~` z4*hv*Y?T|fp@l57;1(NZ>4EQvO~nAazv_6eGr-f&(`k$Z*eOQu1&A3l6$@R33`CaK z#FnQw1+RKOanL(hNg&6d`90Q`2c+L76T@`YmUC5UDKkAkS`^TT#rn-ttY#cjH`idV zj3jV$e|F8%&yT9BtF6svY|+oawVu*AfFrdkFIwFWA0j^@mm4%m#uD#He8xgIx$V`n zmQGCMung>BnX1+(OIQ9SzwNZ=Oy;5)H(j8kII3Jn+sE)kR)420rh;cET0%PN9-Jy> z6brBn`{quGJ#I@cLH>58_J*%H@z(JJjEO!_s3}B;lN0FuzXiyft2Xvds8TXkkd#HuUbs4!XJN&$h**g!x{q7pUX$I2 z;Ktd-kHkFkGZ`KC@|SC1;Y}vgG0RbcagY(@s_mP_}xx{50+> zfPqhx+eopc)2K$5r-Q-x7E9=HOE+s5wec3i2+)dp#V)11brKx7WepTJ4Fd z$e22Tv{%>}g15&~8oIv{V~zyQWLt~px1t3V$OdQ$-@xD1hx$jdmVdq?!aW0@MZQTM zUJ>GKZ9*v9M)*5Wc%JJQ3dwQY3lhWL_XsttgAM-$hta%G9}$iz73EL$E!b6f@M5^@z@n>eWa-DRxo}m;zS|R zl=(Z^M@^_9VPCGac`f&gg3BZUy}kRL*o80eUk!G^5~DF^k&7!4J0;@sz@MSZ6XLxg zcR(QZ-5+28?;~7XGT@jb*6!sfmJavWMY4>uTq%7_2Gc!1nL`$wz?jR^Sr{Ykkzv@D z+I&iXJ~(t3eWv}rfff}dN*04lREcnqoDI@)gKv&;*%3*;pWYX7R9R3WTfA(C?1B5Fm)N1QOl-jE?FUHlG*_H$38eA?je_KBU1!5o zJZRpFrW1(q^(dlh?2LLtc#C*B767(~ICV`l4F5+9N!=f~{F+5Q;3x;E=SU5@z9(=zN+ zsyA-a?{ANw>%kQuy*Pf1U~rTIO?YwPISamwv+1q=ddgI)L$ziO{u>EEa)d;AOi#_V7)KSe!q(K9&nLUc6R8JwGPGcf!#Tuj!hv;fHK*9Y*z`b2>H zYXww@>jd^XC{JojsS(`q4d4~7*fM-f)Zk7Mc+Zlna|#A~WOzpAub+q-D%f?4{PSO6 zm>3fIe$b$+bq>GV=4+&DXpSH8J3W?fVsCvJd<)Cl^8Y6}PP0gnWA(C&C2%js|NQ0y zqfCVYM^+IY*GELel~F7^53_EkEiN}%;4NH7(R?Kng|cCyeOsI{&6dSiNCQrwefpvCP1aJzHc!!Y7w+jVLDgjRdRcokv&8LraOdRVHr2E9cnZ-vxI zZwucVeCCQ>a>!fE^bbYVaRr|ivJGK9NYs=vC$U1=XG@1@a?`f^9Kk#ur=pr87z3a= zpy0{=528V`nQ5Ag>5pDBu!D}$#45)S2VE+KT2pG$`arZ*FoMtQ8~p5wdq3d);)%2* zUKY1qEUX?!4W!_Vd?4-)tY)=34`6{3Q+PtWe; z+izB?)qK>`UmuDJ90tg5iNz0=Byt=iR$C5#lE(}6vmhS5IZDqy6EP;Pu!QvY%Kvl4 zU3!R-MQIG!zIFUVX60CohhJQaA9_1HDV*lPj^idu++T;mx|4jY_k|L01R*Ly1^z-~ zQ4~L>yf)bx@8=-+Q-FdM2VTt`&)y69nf=t9xp^%O7%Cq5GZ}aNT-NIAi-rn01zTbK zZ7}^!pffb%hBDpJsy+jp1b!d)ym(eC88uG(MgF&hF-XqmRPX4(6o~BXO*|}WJVu32 zP2%MAw_LcWgSVWzWjlky$_Os-OSp!1AJZpRDHf^)M{}70kiawf+skaz&|5%}CtbyB?%YAULiztP6ObcnO%mJ~EyQ`}(FN znTp%RvOF)9p{$80dm_5XUzg6Rf@*0(=#cTWq`D>z!X{{1A`~%AHfhGz_i!|whg^F0 zHWs}MOZ0s79~*W&%V5!G0L3^Zw0E(q6^A7?eJ5{5%ME|EMPz;oG|ZXQao{K?>E+GGKKE>uYE^zm*n9y^p|h1Ursv?1#N z!YKywS-Iau!sfn4u!JQSRLQUIIjL&3Y^ z^eP%OQ0NC1JYer9Latan) zfOT?wkc=hL#$T$VS}~RCNB{;*e@bKr%b2Q0F~SUIUn}TCxTUXtVQ?YWBJbzodkC;T zzJo)k=?!qgQ+~%IlIVbKX%afQHI#_ zEOetjwI_1~CuUP~QERO$+hTB+h{fS)P@7Df4fjOq0wg9-)-7+bO8ilAj3_MIh9N@% z*nV|$wLjZ5z`m&R@|wx@Qprpo0WdsSw5+mS?Wxoi3B8*0vEZO&(O&{RRmQHfQpxz@ z^cQz3L!!Iq;Jg^Gch@BwlYC>Jpr{Xc&ZY z5+stB_kL%)jPip41egz5t{KklznD*#lD=RYLB3#9;;^1BN*l^dknk?xf1u$s{UQEV)`b_3=@^NoL;BaGC+Vw{L z>DzB>HDb^7(0Qv%?d`bTq@NadM*(xy`5&{Q`n$<*`jpgH58xm~8#5btpUWfzb&`IrQ)tJzZbY1!>a=ZpfMBNnyz6zu3k z27Ir*k)n!R)h!fzySHPcd%E^9h`0XV7dua0mUNG=nZ1`Kj}$zu?4-MiQ?MP!nQxbk za{J5nE&%7`(>PK+JONzyDNuWe zfEoE0lAKkfMu#w5IW364cH>cGee!TUv0}61tBJBQ{i?IUA3FfD`@P!V1Y9vXWr2!8 zP90m0@&nr!oV%9mOe!{F#HD7)mvIDohmYPAZhoY-uebePDa0m@C8;O90Q#}&j!vnM z0(LUe2??o1QKe!RO&J*?Vh^3p2;#NJ!1L(t@(P_{_vwl-`3}k~!6lD*2s3ixODX=S zZ{B`laTUS2eubh4M@ghl%8_g1P&JHt2xc@ug;vj!8eps7vXD70|pm|E^%Xm`F|b+V`sq3jWlxnq+6< z)M9B`;+o$La=e|D1FXDkCEX+qo+D;fI;mY5moQ*(dgpnLApnP31%XNV}-ftB`*WT>6IRb^4i8-IBVu5kDbGlh*Iuwr)4ep|_{!W>4TRQz}zXwGfc&jz%a5cfk=Z znt@8v=hDJ!r+1oO4hN#-8unu1Dg8%%6req1r47hPLs-n~1{h&8h$_tuY+>BJ2w<3r zw^88*Fm=5+bZUP;?k0T9W1ANe^5#hmBY4+dNzkNBX*T!@yl~N=T3-kGwUxF=f2e0t zjj?^<@jo-M+`IGRNiMh(AOl#5WM1f}xNCD0yl<~cJkj_&k)}i8oZPX5JtV&vqahGp>}}k_*{_L#HYZR`+%@4NP?(qB#ZNH9(!}vf#ZjMLMxiN$*LtTh+vf!8@MUe=4OU^E}8Q zF0_s(*+}VWWu+eqs~By6#!{)2)1mTR;@AxK522Ci`3(Z~)W0{fEbuie{fToFiBG-2 zz#aH5=saUBU$n8jytkf3yj!xOB;3s!fV=r|xkjewo6>u+L<}G3&*$k7RE}BhAqASWQv?6|6Hs;DEQs0Q>+vwH8Qq?bRA>`1SL%dNv z8tL3+8JX-yqlr>n0!0V41Gq{z6!z zEAgtU(3(?8eV`i$4Gcpqa-0{eo5~$#CJHn5wIgv~T19|K6$m|PS(FR32m&_2LkM^v z@$yFBw8`EMcZMTR$IwEh+c6D-(b7Qtm5`0Swbh^zjX)yDTi^rS`EtuYig54NMym|& zq~4$&EO6hn36XkG+?I>XPR~NJJCVofNOL4GEKHSAF|{0k<%_|hx^+Aeky$+No-(rS zCpRutQI4I(1HuFUtrEMbV9E8-4Dnh*mCZsk24wTuAhB%h>0FGL`2TRYvJ*5{kTMRP9c_;RF=&iW z6}s?3uS`6+-$}Sf)b~HcHEhtWL!zHAATHpCwi33 zI%}ncaY>9;<_}S+w)H(67<9koJoBJsb^fw=Kz^~|+7WykQGGvj3J~*86~m%%q!hmQ zHJZVP%~HpU+fAJ7j)eI*_y6oTEH88O-+T342p5`{8zG=rT=d+0gLaoZkc%JNOCK-B_^( zKaFFrH%nb`bWAMY!Gl4k0IID|B=n$I!t1 zRG_mQTqRTWSn`~w6!?9HEu(cmfic{I>+OopaRNm>AN@iM$Ro0}NWPW)83ADXLg^)B zo)E}>k?;Fge%A%lD(?F$rd`|dHylR&=#`V(;s`1*FrW!dYcT$?)zi6Hv|usLTB@PV z+ut6G!rgZsn5XEl+Tuy!HuS(;PH!d%!p{T-a=aFZ;Ya*KWxzoc0+%sJW9Cj{>=!Xq z7$}|0l);*TG!eq5r1ND22O^Hf)wG6ixuVJeV7*YV)eqr>?Y$P!6iWK87B^ejgGqU! z@CPie&42?n0vl&-CbVS-ipGW8q!O_#+3t=^|zA-gLL+(4E^gdkwP=)^JNv9)x{R9oL) zCdmcgZ)n=5e$`VRR<;lqkj3&NH_3Zv^S=(2?+SFe`RyD&)bvvl(u=$7<@~u^@zEsN zyy7oy*|68QV(JXC`2dA!M-l`eQY&rYE#pFX-9z$F89xi0IJ8!?r$fe1ke;)AL(?03 z(JCf@I7Lo!`qCaA>$Q7jp8$~}v*ohMhnno%Yh_KQFZtr!qiPWye9pD!p>tH@WJ$e%DJV+#)rwkGnat{u1e_Mcnu)l+Fsq`MC8Qwq(UFQ-h1es#J0JQk&N?AOTuI*X zg?|R=)JthE36zg*2 ztBZ`iR&ijJy<|>{7%AoYb%wjpsO07xlvPZB&WZ zdR;X(p!sQJrg91pn6el(Wh{!&N>uk3pwB7MuMqw8dp*`W4HPBK&eJA<0=<5KU}=1O z4wAs?y7x@KnyQ0ins480+FM4od@JYrz9>%wg{PtV_&p_4>+PZXR9eMjlKigQSGvAh zx1(`7wp2F1f`bvTNeJ=$(6-!WSCl>Po7^5|CzdAKVMJ5Q8N=MUUf}z`uu9RRMa-Hv z1@@W+=eHs+llrO5$arpt>@azgJAe;)H-50#Y0_ zvVANm#nKVFnE42PWQh*@c*_E-Klk)s77?GWwhAe+P0PZ`(btGU751L)RM!Y3Ty*|s zvs=~*sI^Ntb{CrO$_%0v(d^AC6{wn5$%K2a){n;z2mFe@I5=|l=}=dPvifE4v%ruP zF>ICO#@R9HPId!R=sLL5ms2fP&50=BpVh&;NoIv4fEjGJrPfS@-}@3igJ1(cZVx@~ zaQM2OhuvDmLz!%GlrZ-=rN%0uL9ob{Rvk<-dfgFRnyJGCyXS5J_<#h=4A72^UmJ9f z_8k)|S8~-EliD6?uqnQ;q*~yWjAk)5ZZsb z$y?B$HqTwD;6vtlrQ=S6+KtKU}!9;9EknN5Z zXi}w2euH6EcA>S7!nSO-$j`17`p|X9GBEez<}eFgWzD~c)VSj9EsCkW-GRZFKCqMT z0E0KD?&)Zwi)WuF>4%Zb$~6s>_A8wrCFW_MFK)CAUBfW>^UxNK$~ZXX{y(sbsyahW zEsEF3cW7{G25M@Br2|?BZKEVvb=LF+@R0qk#hfK~YIcy31V}R;92dmBK)(cSw2<(Q zlU~vKTkz-N*-w|OKig;$Mi}`od5A(Xk(%R{K@-|3a|t{%%wNo2)HISIqdZ2(QH4^7^xZ7WY1ik1hzlmsF*~%&8-(a(Vp^S!U^_%_bWwvMZA!o8B zaf_agvd5Uim7b?Me6wevMs_s6$DU|M%8Tts`EeSyr?Xg%!U`n3S$y3zi_VvN9}i%W z!XSm|{7k3UqOB>6AI6FxrQ$FM$30u04Twt4e|IO&QlW$6kWM>Dw9EvGa7h%p=nb(2 z;u7CVgg&KwD2M^zc4>WFQ|xD zRtIeN&WzDGx@fGeN6Oy;he}Y;`a*cqX*o>Cj@eVz9B*~lQ-Vwd27yVS#{}q&4MQj5jkk)JwIhJKx(`-mxGBY8;VHYo%ag| zq^(O{J2YEJ;EkPf)ehqNEF44O0)uk8`w~hLSxltC(bxCjLvLqSFp&T7EtSPwj<(@n z$?l=}YFj7_aE=($xQedmaEEN$LtdtOY*0C*02RA*t?wWX<L{vVDY#ju-wWFw@Jx)T2zOQ{~MG zS!m6>KQO*TyZfSHbvW_Hmbnel1pK}WxvR|mzRl#bEhFgp{n3YL5IH4<+Lp}i`I`XK zBR~no{I`;fltqU!!#z>fwVy$A5=k){CuI``)vZW)x`6lDlJ?}VPc{-#olSAYD3@-h)cpJ2xr=xi%s9(#=nRHn$uCJDa#t>QtM;eQ2})g_W@ zZb1M_`Fj9h?)48UDvohuxgJ%x1u&uZ$qBIA@XsR!&(o?o22c?|J>2@;HI~?_a7dWI zy?40WRMgl%X!oJiU&r5*@w%3V+8YP+qi$-WlqqIsg}=nag8Z|tb{hk~X_@HLZ|MuY zhSy9zC#UY{W#kmZCY{w-cOwA&^0&*6w$j;`EnZs@o5G@3)AMlq=OyyQR`YXb(*7}~ ztnV;$YaqC4s1u+MQ@>t`yQ6TUSxF-Xd^D3-{SE41h*(lwl*3!RW-S^>@EN{qzkry3 zIQ+zCowVy?<`(~f5DauOqkF0ZMsu$Rot!f8%7YHL*NN2O0sfRS@Zy>Jg#fewT<;)v z7cZy}A`t$`U&3hf3dQ?*b-A`oDWn^djF%7b*(ZCil%5T^5($(rm_a6ccf*t)1Q32< zmwf75PgO`<0oNd38kAxK;G(+OB-IJg`Jm964sj~R^V;#5rUN>Xt}fwVMaJ@f=K~1g zrP=}<#VFxzF-W6gs9h-f&C4UaI3cqHfRH$Ga##qrSO6y`(Lr;T8+`Eeozj^p>yV_7 z9W;<#Q9V)gm0ZcrI~6H#CkBVgnQm72fcqR`9oCFQbXPjtI^%cyI@v?@Z2rzzOq8`| zO(<|NN9R_s*SCt5lrkc+yk=L$k;)gxf14caall1!L%zShy7Dy!DHmD3Cz@Eh?uhZ5 z0-VlqZQv5C2Qw4WVaQ3Tw#LI$*q6{|X-Wy0p7@*HNJo*7&nUS(oQUR{%SH3I;ohvM zwk>i+w{o@zLjt`zpiE98vK|rexo6vH0QsDyrRHqY!-D94H1~=`$^DCd%nA>YlRG~5=j_zJ(L@A)Sj17f**;V zBEDfkLe0}3)3(VYqa@UvO42ac7BU>HT!7r_u9Z!LgWgUeOou%bnAwiO+c-+Deir4C z2v-A2lYj1R94E!K3aRSiIO=#;==UbUJ||h+h)IF#fyt7M^rdCMBwq1KH^?BnW-%!v z&Hr1-oi)ZezrXrof#phAd-nrZpv3;YH{=F=Ban+&@80+AUEbEdO82I1K(b#nn9?ZqQS-N^b?;iolFXs7y$l7~?U-?dUY41t54 zvD
*bm3^)yr*_WVQVL-3)_qF>a>G=QnYGc2M~L)SzUBGhX_+JyvI7J2~PCEonBwv!r^3C=H`G|3tDoDJ@sEF0bVzu&hHIvA@Nm%_|5Rk&O{E>9QD>ZTmmkQ zT=63CqkjWp^=IdScC{6YlrI$$n=2bBco-0$Nhhcq zZuA#@KA3jw$NPwA4xn=d!FkIrQ1cQ5E$ZF{u!y{6RFe$R+TbPID2AF0uH8`;-+CbZ ztSN7Z#j~4Ql$~cD11_Nu(P_i=o(z)eJQSh}d}UgCEGQh=|4l_x5-7?2dpf=K!mkh$ zC)TF+{Z_e1THRMBrF_AB--Y90p^?q7#wuh4St$o0wfZ)H1}-5tP|iYO%OYH9KMuAHx;!|7-KGoki{r6zj%fEezyYB79h@=a>W)DB&kGxwy7S@ zkR+wNpz{U}8+72P#=U81MkK_{ql494*sduebJpZJE;HwNbzMkJBw(s#)btI*YPMX~ zN(Z#DSPHIE+h79^gpijEFE*qTb>4sp=aI4wEZ6ZeWr9v3XJx_R$M9B_0p6n?L1@^n z@R~<{mt?)AU)L!mIA(exVnINN$sC>6qdA|2?Ig>hlz^rJ`J-&Nflo#*xMA}9Zw!Fi zb>_&xL`*cSMGlj-vSUUfIvSUFNyV(VIwSxn|JdF|%pQpD;aQ@Fk}ywYlP4&BJ`uj$ z;H1XR-Gv%WA6%Z{fdsfY1Lj$soume*2pcW;H%Iy7SiG28D(#qg9JL>m2d2#G9-3xe zqS(U%P1N99D8*ITY7E8xk8pCtOP}+Sat`Az^bjR#k?dTTN&^N_8t@GhJ{T0wXUQvH zo!gJ%>r?P$^9Du4DQAW~)wW2LI$5ssI&e$ZSRC`PFMWq*DACF>34RL;YaetWq4oPe zcOv;p!>P#hR)Bu5JZ2rV>UI3NmRB_t0csqNC)>cR@wa_1Hh3D%6#r~IVflVP zF*d^O*F&_rL568MX1b9ImNQ%+lvICW#!4|lsRFA;X&wRoX()8X&Q-hf$S+yC`GcM= zs?KAI;j(4I?T*;)J|Y~~yTO$Z^6&rUht|0FlT{Ec*OJIAWApr*;!1NN5^^ByvnZye zw=w*+srkIJ+h7q|c^ERA`vYDqFf++sy|$IqoypnK@z5-!LYwn*^E9lBv|}9wU$Oq> zsF?DHpZjP=;!FXH3XjQ>k2}9DfLg9s{Rqx!e--;A96MmAWuy6t3S2+zD{o*o4I8ut zfLG>#fhos~qXOEiMt3Vh=5ubo&etBwHKIDS+ z(AsfTveNo}rS)>B?o%Z+~E$Q`AR_M4HJrIm21u!_}@gmG7`4_iDc4-KLQZL zqVN9!sL#!Y)2}-Wq|E(vH_NN3U7&zV=Nqk-NeJDm_=7$6!%I5GH$8_!qG~t)g&f#u zXqGK`?p6-5pE6{5oK|FNGFh5sBC$i%v37cvib|! z0pjxDd{M#ZY&<&Xw%(p@0eu~Y3-57|!x*G1KrtD@QDaeR4wS5AKO97dAF;t&hvHNg z3E(QF5}hs`=r{o{?z>WMKh-Vd*T!S5U!U_AjX|#&Vkb1S`(K!8N#{df@Zh1=W-|fGpmHHdq<^7fJ7`liO=a30FY9~di9K7k52!L_O%)t{YQC>) zohSfQ0DWjNi8xcc&BO4Y6x(-rCRHrP;$UHo&eLN^AAq404|(wH@=>0N(O6iUt1dFM zT0*m10DNF(v*XExYS9PXR#BKyyLl5M%Nfsk>_+k6)=KKd|M@6WaS*FrZ!GahV{5Sk z2h;x=zU=cY2B)&x5ag3+3PiuZ+D|#GJka?WokTRc(d7yR3s-X*l-uK zF!jz8BNdxBW2m(UlE?vZNxTHM#MD@rmLG+E%6F;6bEa%OYqq3KVlf5_N19*-e;EJz z081Q}R&mQ?EJ&QAsjHwnyZXwIWCMg9mazXDS4aT%dfY;Vq6Rk(vcrR$^>{A;GS^a zVNGN7G@qcuibubQ342v`cadHz%y~*i)O`WN6?ebbRUv#;M;)Y`&Bxi143}YsU{?w8g9>W$`(4O#z3~TgZ z>KNb*c7_g8+ZeKxt2mB&6{CDYhLYv&nvk%lc$ja!=Tu3K`wjCX9o#KH4K$_OOW?G? zU1vDP^U+AO>cI`zx7Q9)eV`wps7X|R{wG1ktIZ% zUS$b&q7D!;a_rV9ngq0nL!Za7*Fw0x`kQjvoc@~#ldu&eZ;s}QUsG0SE3yC(K zRLK5;#u=fxRBRqI5tu~rgCqH&Gc^thhD5Pk)15x>|Jd+wL~xp!ij%drM%W)gs}o3I z32qF())%-I-idNQl?i52Pr8Ifr1*;+`qaR2A}_=*v@c)_)_k=}@uoc&SE)Z$?_(k? z^S0XQ`Nm5_q@*2`P$`XOr=yrZ=|D8J<7@A;3TU)R52G!RJ# z0WZU*ED~}`x`3Vlm zurf(p=|~KgQA7+$*VKo$u~Xh8^}bI)yeLj;c1IeX9F}IE&e<3`Rf9=1>feAn_R0ju zX~-LLS9lnQ`LhnP%7D3Pd}*k`3Y+O*e)=6|wPjs|E(aqQwqaA4fFf8b<8eQ~8^2Rb z4k1wp9(c5bCh6-Oy?y$m>@vmN036<8EfRiDuFO?)Y39qrz3DchYjdI9dqR=zJ)MGT zfEf2vLzF!4<=g)(5+5EQXYpY2IsPht#2iivNUg`Zh!Tcx@&U@E8XEDCsQtoM2 z;%xHNh>*F$(&W`;;=c*$a4UiA27d10NxCRK{2||-y;@q@D>+s15}!aiceA2 ziYtp}2-3?AGj$CxcN(dN_E9wQ&RF2Vs#Ii6aL3`gk@yG;}8N)}37DP?i z3D&K8T|{6{^P$!$!`>X6z!%?Xnn*%K*phC~W7G`gC5n{uhm^vd8a|9-OsP0XXV2W` zb&(<*-j9ZXu#73kgBv>;KEbD_j0aJE<54AXH|;-h1&5mnAU5PR&)JwRXBR?Oq$AlaTn%TV zzrI#?8)dwZ-dxx91u;}Vd3o;!tlJ~bmCHz)N)}$e7{*WP?Dupn(pR+J9VeOXwR6C* zBfz?*5|)6;qh|)m+7-!1bq41l zDn(SaRS>I6v_{>p8J>9&K;2(%_cHjJwHZ=4?Vzn+tDBUE{(#=@+Z^A-N4FXkh;P+i)ISDB#-ymb9?*X`TA@ zn8L<7=tRvi1F7ec_7B9+H_sg|HqB351>iPOHfzWw!!p^hPqr3IoY{}^Xz1&y)J*KH zLMO^g**6jT>cdccV?kmBUrA7^dxmJH+p|jP)N;~-a#h(#fdfvbRWbpdJqzU=|F}-aK z4G`j#8VP`_qjBsaO00~EMmcBg3Z;41`Qp+Aj~NsM&9~s0_{*~b3^r(qa5*Eg{PU_i z?#gp9fyqA@YRr!Gcd)8Z51-gM{CV4Vu0eaSQ0O{v$4il?L#dA!vUuloQeqX$xe@ED zp2FAZ7YL%wqFy~9dd0FIxakmpvF(%C1skNOo{G8DH&>SsGmg6Q_ zTeRZ|RnRGIlsrT+fvc>=^#rMGGX`Q%P(KTCw-z#CY;1?+#h|Zq5)2jdy{^+bM+H8J zJ_@2CGrFEulxywg<#%E}aw8`Zb={FSE9cmwD4T*z-_)P6Fo>*?Ae=`iI$o;@G5w&b zye)Jv8xv#gJ-%%!j?_f;RXQS6FS{o>L>FC}AD_901hjiuxl7&>xo#% zN{8W>x9hXd7?u!lmIS(ZtGRJ60gr;&nBliaOza^|G7_Mc%-qq;DAF%^g+*A|nrG zSOtSH7BS-LM*sHPol_UM`{f5h;VE{D9j-RU2r!5iG_jV{)+IEKxDQm;u2B20QuX%I<4<`THko#g~ zzh{zW)?~b;XNasSf%>32PCXQ8L?RWjot6T`@0EiXH=kJ(EahP`gP1v{k;jTcwkkD7~Pae)v3MBT`m7VXXWJSo-h1 zJli4ZG6;xo2e1|#n*cZTE!`ms{cBGO%fOe*^z~h(ux1$#80vTto)EKo*kOKfYYLgs z67oyP_n>L8_7WsG>=_~yQGXMm4tzo}eB@5H+kR|BfHKMG&oPYkT!T;>4k6;4;o+8# z1t1$kR3Z3wUGhH$RcpWaX^`58AW6nCe%+&jidF6ZU~dPP=|*A)MK)sHCsai+vI$q6 zAxD-TE~r6`ILRlAZ=Mnit`fkImY~n&IVHmy0@l5#<0dxzXID zCLZ>K%ak3}M+#J~e<`*<EDB=@Jx?|Inlgpl zQqQ=UIT-KU`x>r+6|Q-H#h%E+eQwx?pPl#>HK=6C%KR{R1&KY42)~13&PA4#+6GUlJeb zS+bY9*r`^A1njI-NAY`ex<&TpY+jXEA0qxLM`!YYwHZ{oXy#mwC`#xDdxG?**|#;! z;>3uXG*KzWD->|SbWg@jv{Te|a0yr8mRNpl$=HWsAu?Kf?%(PL@Yuv+ML^*b|4N|o z3RnVKdz3Hsh6H(X7^!MVloZNV%NqCjx~4eb=63q<@Zn8sUPjdaW+K<%S33|{1inav z!9;dIh-MJcrBSu!!JEHR&ns|v>>J0lMI5|j=-q^(?GPye$1fTGVRy0-ZYjjtN7=zg ztFg;#g4Iz%bz?ERwX*e_7+~yzkBofxi znSqFz|D|o34Z-yT?!WB6TIaAZ*b2IK;A!o3;pbq^&puAGk6-i^sfbG9HQ2j=mqxcmT z5j?0dNCD)mB$w^y!tA3)dv8ZTfU*XSKl@G<(reGNzfXk`nXFLlcQJCk!D9^9KRaO? zh5xn;CHdPf0lIFQtX`Wq3)>a+`uW~Jd!B)bc3KOGtscI5is)k5Tc zgt)Y=FOuSJ*cV1_KW6s41N1t+eqsT@LD@x?9b=EZ;O2V!5#v~4oNdwz3S*irk{)r; z?WORm>?FpP+=RvhhwtO+$SkO(3Jh_~mB%Ig(u)f5&nitaw-$;quRvZIl4)3!OAwf=Z9{g?$ZShq zTLsFTEhv(nMH139XB%P5s~2D&c;CPeCCjD9TeVh_tY$-ZyA*l-lEG+L7O+GC8u5@IR=+U=aq#{=~3qNshuVU+kimdP?aC^<~UOZ zlqMTyugi|#^7D>LY8BQ*)Y0%dlZN3XbcLY@YePgWKSVKG70x=vg2rRaPjV9{ zWXj&_B=I#brIc&Dj}p}^^Z(JbnII@{*SL`4wTIE0K{JA1vI#ho3e1j0KW>Nq3nJ|4 z4numa6X)OnRfi|Gj6|u&dhBiJ#|&7Qp~HjzA&-do`*P}prhcp3`0584d(5wQ_^NI( z8(QJ#fz8e&bk9)4+ai<@L3A!bY1(EqYinwR2-=!6@JjAeY;6hD=Kyr_pD!g>N~|S| zIY1HQ;UBU~M0915`1$}bq?v3_ahbC`2!X7GdDz9t7CRDh>8))1DQLqb*$oPJ)uAMNUyk|fuSJZ zrkApWoFQ7OLkv2-Z>FG!SgkU|ay?>xNIz$UY{^gVvwg>6Bz3}nxL%beM(d5<7L{t( z_4=Y+3UV>PUpZ>6S;s-Yh!P_OG@EJ2Dwdo??8E02POFtTcvEZ0>q>9>WE(xRMnV_; zxpC$E{{ww9wi~80)`ylW-}db3ZKL#=8D(O~z0Ij!@X(*)4`L0p-ggu(Asax^GoepR zPI!#EK$zl2N6=Zry*;=(TIE+?Qv@IwIQK9_?(CVUwTznee*xa5Ex9bq0`IZy9dk{K z(!=cV9W244!|5t0rxJw;wqRxpMVu)gYqHpK?o7NN{UQN!hRe?rti_tZ1pEzu66(XF?-pPPChctB@RDVM`W22vQ&C~+G+FAqvo z<+WCet z;yx+Y(pb@>|G6M!VfB*v@TA*qF8BfBfIV@ZD1nX|6AS%9uc3&M>_EJRdPAr|XWCno zTpR}^(E1&fRaVqm zkf$#;wwkOMds#u77 zNdR&jT5EGvh(kKk?^iJ@y>MLCA|=C~uaVv|8gvM|He_yX%Ay&}$uXNjw9t-;L~B^M zVuZs7ATcLgR-}X-Dscqc6dI&+B6D0kC@({l5M9vK`azBSvfT zYLAl8lbE1$79jM-&H}|Seov-BHum4a-S?JHu<{3~K&?3?LFzV16i~wrB-bKc=A4Xt z*?9?elFvXRRDeT%1H)7=26iR1U?gO`C4YzIldmh9Zg+3jHc9oBe;%;$iBv5~zpyTo z!;x6*?H|<8zp>Ty99O<7LR2xoOi>+m%1i$|1B2c3oU z&(&uYx*3`ef=Y!n_0-i4xyX@RRWK02Sxymyh1xE#Hq{#_>NF3-yVv!YcSEIyl~U)} zCFt7HQvKy%8Dj@oZW`kP4?jCR=Hp?IPy?D#Kzk{_qhh7jEWX^G2U*(G>^j3IKDiRB zNdY8z@C`n)`sJ3e4~?{f^RSiJom$yH_BD^hgqTF@fI<5~@)MxypO{`$5#Ss2wpbrB zUOjw6aBybAh*nK|Y{Y!Ki9|=sBP-x+Lw=TVQHx_5vhxU}$sw^-{!2M!zn`9cHhOJAfuG_}j@uR)(ZHRYUX zr>T_5hn1I=%Ez>rv|qe$Q?SVzV2XDiG^Fv2;j^lqbvzS^Aq!(7Qn9ae@*^GE^ph$P z(1OBj<5mFMoB)b69-{4uzJ5#}j9A)u=dp7b3&&&T0jDUA%WejhFJ<~e6%>QhUs|(| z1RtbaYA^;V6zDkTi~-h|vQik~ArX~L)z*W0ih@NnB|#D?T2u4Lc8}8T*f`MXPcY&i ziQc%(eTmv^9>X0E%ptyhq@!fCGGh7?`(As0j7a5XHoV=aOn*3O2U zNOU&8+&WIPaWuP!uk~Yx>f1=vo`2(h(c%_qGk^W;!MP( zeQaL^ABi0s<8zW5%J8m}-|#*UjWPWKTUI9e;VCYyD{(^gk-&eC_1Ltx)aDiFi5st6 z%~@r?Gq#6oxY}M@$Wyak(U0G|SAI0621PL0TlLpjfsON3n%4=jNsg(kWwQa0;%cRr zC>2T~7P>htXQysBwdmwB`jEm(p~h#tU316kz_Mh4CHgI2%|%{e|3Z3}Ate5Y#oX51 zszN6UMd}pdl;#}-p~$QYQDgR4G*19T@+glG3y47anI!>wrF+Pf9hK%2j8tyKB&5>6 z0vbA(dTR8|;YzKNM+N`+*^YK}J-<6uq;E4-CNVw4p6BV0?W*^vucovNtM>0EP=rR8 z{d4&fuUEVi>4Mh$2N`yx!AOt*y2Obkp-%iAe{ix$-QVlmalG=6b8@Fm|I^#-mn{wg zkE@H+8}&eZX-Ypo$p}N1^wLdt zL^^4o#lE>*f1CM}u!{l{5R-R9!!sbnDNL*sCGfNkaI>xSwlir)h=BMQ2{a$S+Y-Drtb*4gpERg5N>B)ao^q2zNLjxFHLM4{ed_ zcAR31$n}tdnc1)g-qzsJQ4XJW$Ea;uBOX=(fH?Epx^npk*dOz-ThC6yuPxXZ?~gNl zjW88cs z)}-L6u6O>)1g9>?@o33hoyxGVTW4Am(*#cZ3@Gk)S~)oF%xLetbjv!i0?+FI@$$U% z^>V&^U9O1rQ=W-1^AR^rAgO~@`R^a+@!Y z9H2*_U>yax8fu%*{v`KBu%yaZC zb>mOXvfGZZg=%fUQfkv!v001i5*+c!hWT`jIz~nwOpK$#1LYn)XovBIIIeEb{pf&l zZ%3&LV%z=e$hHEQ)8}9i3AEl_A@fyTqIO%z29r~4nc9<7-jWY47PMP9J8EGi1*9O+j(Zm(&+dZRU@&udIYu@eA<57X z&dj1SD~;D_q@uUkL}iTtfu%r=3o2C^>8sZ@Lds?(zeYe%c*cLocMI_z7Xt8HTPW4Z z3(Yw$*pfkrC%9|q{RUyy={1y+X}^ z5K#qch=yiFk@t6gP-oY7dRgsLxA_Frt%FL1cyQdnc~$di8^?$KX_%~i>E})(xLHyoxG2S+uiJ{eN=1#1hekW04;p)_YT!TTS`PL@C zl7xxKOzISWDDHQcDVt2dduf&c5zXyvEJLVjYoVC34NgIF{nE}F?}?#Ja~@9Nr*1^n z4h^hAp6_rP!3A1d^x&9F5tm$CX!tAq*AmJfxc3DTy3pn2Uw8iUqh_x@US3czg2BiE z?Umvt<^Un(eDi94IFHU=+9Jg$W?OS&ua|GE`AJh+vJ!{- z7>_7C&f}rECy*3C0US??L=Kj0MLIRTQ&%*Zw1;^4VDV4Gi?`O(NYMO{A!p2ljV|T? zegz$)PM!dC6OCmDeo4(`$y#>k+rm03;05^$|FS zo6?cuU0IuB_muu~gKX=vj^kv+*a7=$g?Fwy)|h4#rBiIO8fyUM=|F87=@so#-?vl} z;VCr9M+t*o{Un$YKh=lm3i;++>H9%8p z$h|Kv3BAf(`2x~9X`zi|G*Wx&v5k}Xu+@$8oA5oH>RE>EZ2lBzMKK(FioFtMI*95& z?|q};YC9r8exocy8fx3*-(<)pId&htVZ){H(+ffRBjBty|w)_*N67%+KkrH~oLoWKPB;3%M9+$;g%LobFsiV+L zQSEGdk=tQaO3lGwX{GtCr4#$j8ZA7B#;=4Kb9N|wh8mCLWqthXgW0~! zmwVc2e!ey&nY`GQ_sUBx4*$}6mGD)$bDSmD8F+C@xe$D7$Hj*%6KjxDaZT`M;mUHi zF)_gGYaFeBGO{F1j4^JIw9g_+xIqZ^{n~8OeF-y#nUw!zJS=r~G!tYhiy8PJoqn(Y zK|sF0IrFc1@a@;fgRC+Ffe~F@Dg^b&* z+;pNQ2`hpVgAqjD!r&V}<_}Q_@HjRS1<#+v(iDSr!^-&zvAjsbxP=dU=h9rLXvBa= z{vAN$FXntDjRpEB^!087I%?9VZ)y^C5&ICJORk&GyYXV%!U&^TXIy)5z>a2n*@H@?(!q^ge;zX;FcWP zN9j^AsB_fjaHgMqiA3BE<-5JQa{39W8QwWP4aeZg-p^|THh;#n#u(eq0L#yGAhO6z zo{k*XZGRm@r{o1DRP1u)UTb*z)K+05kh~T6Tt!K`)b3GnZR+)u@11`OHo4tN$OaVC ztvRnY52@DaQNSt@J%;kS`D+1*R;5`LKMFTMSO6c!4m!Hp9bF@n*?{hQ2C*R1wOR@0 z&KHHIy-bC|UGJMYnon_RtQq$V&(T4l_I_6<^*YPj`_f>Dc;ynJp1p>_#YU?k$gO0Y zmXx4%w4~MQdAogY64+hJdav~&x1un^*ed?LrJ$_H1$m3o`FnM(tFaf}r7sK3tCX~d z%aoFG9htx1nn1=7_pHnKqyglv*!Z8FVc6Q%|Chs@*tv>cU}O-3>YYjCrj8NIy>Sm* zBnYyU3k{GhX;&$GN<=_fWqpN_s=IzGG%4{=O~Mb9eggpNuY{6ERK=s~Aibd@_scoj z%t)7dOa<0HIy9ER_HH@xyc@QvJP+4g=LlOtCHAt(O~Ezlz`ULG zF5Q3CTdCVU3eo^F4yk0!gp;nUc8?3XSy4f#+qM`+exbKsmhdXR<U$~mZZC2& zq45jbRma2Yk1gj9yLoxZ62k`S#sY#E2jGiChWBw{Swn18tB*bE)p*~Xb9CE?V>UL; zC5YU%G5)#bVKJ&OaG0$Z*NovfhMQE6yp*I@aO-6f1E?=dX;yZUypi0)j>Mr~gj5;%Bwiz(Uw2bP>TGy{^*Bw_WYpXy~vPX=$K%y6iz*XH~lO zu>Lnb?3c%j+Kav@xE%1vO}n8D(sanu&MbIke6j<1csm_=M28SfwuTTec+)KtDmNK| zyOBXGKip@^FNritdr1O$QZq@sFyVr~Qtr_h(&UWE2T8}n7_xa>e?B~q!wCuU<3$ON zm0Y>9xg%NblM-?>ee-qai;|_z>iwECDnK8h{nDqR8u1($j`E_XBC^Jg9|WvU75kR^ z8drE_Y~2C((F9;hs2FeWI|~9SFN?K07sJapT>bgrP2MJwh>l^&Zu7X|epl&j7CbE! zL?&;ypcBN*CgR#~LtZM`&GcLJ67pod(VRgth-hh9`Z=KqYvp9VyAK7P!5e3%FQ8(m z6$#N5ltK$V>p@EvkV5kAP8q4Dg;F(1`@C~c!Osa$GvPE7`2vpn!XldTY>48;l{e!A zv#$XoWG!6b_07i6b;b8(uuFT(faN5|NIml*{g8Ovwy>sk&LxkTcI!2i32JULlE-!| zJyg-4&~tigUY7@Nus-%L&LII6aetx^>lTkBykd1w~ zJkFAYM9RS%L?3|Ali-qPIl=kM6Af)fSG4OazvQ~{R@!mYCEH60L!>w3&)vHs@XCZZ zLarB70pA-SN|y>&2)#dNnA2c4fM7z9KmEyBE3YF;@s%NsY7_Vr?o-+kVgH6$s_|cP zqX4xKI@|OC??jr6vjzMpHgSvJe=4j^{6sj2f>j@)(H(sjPPNgw_^e=aoM%U;K7bd> z_LB-xM>_us7@&NY&G(evyVT?z=(zJGBA|jAgD~F7r<$x)hI}tB|Fn$1W+BWJ<^Lm_ zrZyJ!0==*p_0^Bi(5*-mh-|t)JB0MuqwD)o{C_IN%eqKntv?4?0cN8Cn`jJDbju?Z zU#kkZ#lEetfj{jZ`02ma|E}MI1tiJZ^R@F$veyuRzr-+4wYALoOUmXHNbkc1(NsU} zLJjn5;A#Y?OMdI)`rm-$YyFnz(o>H~9%kCRY60uMmH2w1gTEN{(J5{11@I7sUM}1U z)zoaMS$3+sZ4EK)vY*MYuNUQWQS;JFcw=&5j(-#DwKZ+CfCxOq8=jchq57S6bUU^F zlFh=jJDZur6}$I0M3%5$^lDP?C^u9e~~ZUTt?ky=5Q2drH1= z0qYANMuvnF%uWA9mc{&?G*S<2&eJ9!n5kDdnlc@VxmFWJvB3W-w0tuz(O_F$#hdDC zDa4kR<#lgOns1oF3)uop3>xl9B;D!Nlu8?7K~8}M+HABWQRlOLQW?+-Qo0h(a^^c-KsjVeHUz&}+a zsO2;_kr|wj0!Mxq0x_GbQ+<8h(0uyuZDBcej8QvjFaE&5zT~87 z{LQm`itPq?1Czx`!524EdK?}AV?>{44p`R$*FPbq-j+8hkv@uPehh7=;UWCkT1XOWNeCD* zv6Bq9Okqk%`7{E4Hv?*heLJ+~)hM!p%5Iv2TUq+=KJWk$bTj_P zD8MV03Ahv|VLmh*&A3Hj@M#J?z7E$3qHUYjZue@ zmhC8CBbEGeC2B+uLuxlcq+7u%``sM3K;LjBO1>P0-V;^=()Df&IK`RsX{^ZZQ#q>; zEh^8d;bQX4PE`_p;)u6>gFMkMg(rv_@#0RAu?V__tOY~+%xyr&N$QQT+3C-Fl>*sT zKznKBabPQKP@uP3vADWEd{H~7VLiv?tUM7WX5f|Nlktg)kdW3q3dBU&t9qn1x&ONrosf81%;N`ibzr>s z(C!J3|MfSWQ+P(1ABo97uwteSf7K$-9uqgS^GOoPp?ATo=DKRCBNHgO)N|pM)e-h+ zDb#5pEjz$cfn7>BKXGQ~q*I`BhZZMz`k-S zBh-2QA`ipx!CG}Pl)K20L?uZIoLtyk|^EzuJ!2$ z!yc)XbH^gRhfAO1ddIh>M4XxJw_Nig?8^~m~Uyl{tQA2qn3JO4T!>EyAdY(dtEKQU-!l?4ZAGnV+- zOKvyu6JO?yH>G%6>H0_N-j@U@%SU9n=$T#}k0fX1Z9}@(AfF3C$9QE7VWGQI%NGkw zgKx>MJsF~z$3jaOIu9qj<>yx@bG9J>u%q;;RB$?eH**%yun!8mi@BOBvChnyrNIte zT2K$-t(f|^(p9j~mb8Siw_@kVjaZ`g-^ynkrKA zfwVay6>+crHbv;2!AUlfwH2KkBrp(>~9rP6-)Vj>vLcit~n{KO??mrQ7Wd zozd@am6l@aNWDP4H^uGwo;Yr@tuHpSvMxY)ON3$Z!=S2pwIoVbY0UD@4|7@uO<$b) zbbL;L+ihcPNuuWKNAKR}Vq%f|AERoDtbU1E>n{Sv5;9n6HA-sd#o^v8Y~5R6p60f~ z=UO3VB`@wCueJAo*idrO!BNt9uC#v`wN&-Xghj{(4dz{pWtJ<3$+gO;FZF%(%vvM| z)Q%ZM$GyXhB&a(V`BjiYZ?IJ0%TaJU6EDWNOkF@!>s>IXyP6sxXLMlvQ#DfU!z;Zp zfQ~7&JeH^s-(!ThgXx>&*ltt<@aPim= z8a*B$@gdX8f;UqY3&+HZ6WM@YsTV!de~;WT{An|0Q}&Dp zw!_^TYjB?>YQAem4AR}1THe8lj`w`3J+!P@;WK#g%pqp<+^V~1nCi4Cd*8D6$=^G2 z0pQ=yk>BVN2hHxhoH#MOCTv;d4z6)8Z9I}l=}QA}LrOt{@CP!7?ebqhJ)oJEu0d); z62vF1DBEvko}kjhe)Im(Wkg!B%x-9e$^DvLgdhkuIVb>w-FqTX3qscJ@;qP$a>^X%EVZ+l|^7&a|Db#;} z;@2hd9e;S-CS7d-U|Z-w=1@%x&^HkEE6%tXts?R<}hrsCfBSe9rB zN?P7POd+#;#)C*3s;idVVlAPaEk;yV+00ok?9U4~u2BsZ06%J;f$k2qJJS!>5nz#T zt#fwhHDn%wIX6UMqSsVM{>7E>akoTnq@{w19pU7}G=*sxy366zL62%T5ghlKpsSyA zXnkIanqiG`405up0@gOne&-7+gT&YxH2o$aD!kCy?1+2~Yd5>YfyPl;_me~(H6X!~ zm=HNC!71qULvi1}RQ*d=Sn-#wn%UGH;#1{2G5E|#;)~D7ZhmN9G6rlUz!&-TOn8am zfB-Y8+ElP+*k`vLi)gTen(iH1D%DO6LIMV)@>R!L<(ym{c*H!sFQL(pqx$C`lhGi zRI+1>jFeI5yEh1c*zapoeZKY0N#3FvID6b8=}bBiQ55tghnCYRib3F-z>{kT+5J%G z@5#h7A4y}_Zrb6^`sTVb1*2||VAiyoG$tj*M#|)(=2T`(_r3OZF-Q(o$$fmUH0!J* zMp#*!LV!~jV+zx-V8&TFf$j4Msuk+^g<|!&o>~Rz9P2UexS4y}_Mq9C%Ps1iJa9lt z83LlgGXN2K*inHqCf7iv#*P`%x~~puJBZ3>jEgZ=yCFh9C&*d(A>$FWKRX$ff6dwd7&$5!du z*{TO|7so|wg60faSE>a{R+=T+saJZpn$hs4{9PLsKi!$C|Kg9mXrzH!J9Mkpj09!C z=~fg&Mcb=k-aqv(B9PZkwk8_9rsCj^$6BVnVKu93=y(COBI-vuwJ06gIt0i`WYhJv z!@T#jut{EGd}@;eky}SyL+et3h8nqbsyd-!07J8j=!+f=$t`l#8{H8-Z)st`o0C=- zjdcvijE{}a2yd~MC`_`;t@U9xb;+yHRZQC_DdQt>yoXv;9&>NtrYb!wo2ZB_!y28m zbpQJxA#DU)4Qi@OuIijLu+DLLpO@Z%ZnkEqB32=>&BgDzfXX{mvrgqh8w;$Bjbrrl z6TJ!c2fxz$ca%f5seKuTE4&v{;W1ZUSCOa{sa)u1GzUe&y*l4X8BgeNBf9qU*7SCQ z%@-iN9>mkP_uPz4UfK!f?4vt&l^(n`&ktdd9%~;(S>=mT9jj6TJCaA0z8+0uknTxO zE`+N#4;%gf4UqT7EXed%{Lg6O*s+?0q~>q3ChfWese3kSFp9x}qW!}`2f?bpRhe>} zeHV;VB@fd~hd(rB$DLPZN-{OGW`*GHnPMd2SPy=DL?MWl0W{5xk_BoNkZTA)XEt4X zuL%h7lX6&tC1p86waMhTUZIz}dnI#*P{duS@}Vx!BoFT1+QE>nIAIu=*J5rXDk6{aJG?;{4XKl2K&)0hTAEr ziPqY2UCT7Y=N+rj0;lp+*snJhy~koHWE8y`!CoEv+_ZnZQgq9jtT4wc9=QcTlMT=` zRtr-b9_dRxTT{a5MjRlvhuU98Yv&XQPc5l;0?h?wpi6JQ@K7VXZP_^3+EnMi*`HQG z`vN?Vnu1NC1@b0(k*_L7SD}PLpr10hElkF#-bfZ@s#s*2su5`at3tjptwxy zrGB#sxlUjopPbM5-$$a096jBW|5o4m>Ll9ULA2~!3nq7nnPg7(xsWT}HES4NlKrAa zgPOWqLl5Ju{Pv!JcQ&(1ne8c`Db!#dGhj!RHnKN2lo*|)Q4Iu3LXIunZTOGHw5qs> zoAwPrHA&faQ+$XbAGv( z8j?>2kQKmt8F}2-H`<3{DP_GH8QCRZ{017@X;}UBwYMCzwkx-ojSzk}J&e!0j}kPo z$jPsh+@6OTCsh2dJR34JutM7ct(Ln2&GiQBDc_7}euR*wLQL{VkXvyK%DKl{wt9m3 z>^DY7lBsMtRJH!(gE`su!4=RA7PgB%e6`wcL~7YiMf(1wjW<#KdeJCtXzf_V2%mdR z2E#l*F3-wXcc$Le6SzDCEPZcpyfae9Y+A<1lfnw}rI58@;l&qh5cxAm?CcYG;*>|> z^CamciptV;^qGAc&=}~Mkxm$}f@-Tjh{+4k;I858`4}}1@T1Qv$4kd zYeEU|T@z_5%lWJvc+LPuD_Hf-PSpwf9tRsyoBi^g(s&hA;TQJ>jA>DqJ)kI zyR7?C4?0YKN~k)6U~JJ}eN|2+s=Lf}_I-Jo2u4hgKE0K;oo?{;KQvT;vcscw_k~%|&ZtQP_=Cm{X+F-FUR!^aumZLxQbUDKo6}&~iCeEYh&BH)d%Ll$MgZd> zxYpf}gNAr|(Jk5m74;-{L;iIZVuX5A1#h7EW}OI5B&8!|0TC)$QG&RkQ;d`UD=d9@ z(1Ex*e{(RH;vO}RB%GML7izeT2!+m zyYnGcjk@>ACJ&G)7}TvP*7Gl>=>1yHZ=ZR)+lvjm^)ZIDvbSFsrtXxft5D+VutR}1 z*qcCC7yk?F#F8%hFqLSoZ_5jY`mmk#G(Ug!>wYnI(T9g`rc#SkS`N57Qu?b=q1o5Y!{yR4D|NU9O(F z;iTpt1O=zPhoqd4zCC+imO2HJD~9UnkLo4$27Uv4xy~Q9fAs^`V9)(%WiLNKnV~^o zJMkmxn@C>MpOJ$n91~s{>`fXIhmCPYW-&iNg{5dipscPoHX2$LQ;~R!oWl3R+=LX% zYV%DU#6fD_ApFz`?fkb(p9QKkMOGR67sNj%@QT21{uch%(3$6((x)RaM||91ob<@A z_S);^aFvJ(Y9$ckPVrxRUFP?^(vg_h(9c$EEjX1Lh1u#pk}8j^FY8q}75|o+5nY9% z-eOM>Xsajn)C!S^Mrb;pTA>oahmd9i=NagOzmA zM@0duygANsWTtcTGQL z-)iBa65&Tk0N>J~u6I;^Y$N;Gm=ZPl0RG&8tnz0d|9Du`ln^9Qt{CQoI9$=GBX5hZ zk(_K0ojDf1yh5XAieH{+MuEYtNri+I{LdtuVEc#+{9pUCnj*MgZuCY8%7w_0SI>xe z>5`5z|NfB6lH@euo8m9MT=uO73PL_uj7Qc(1c8x z8TE@v?N4$ZjO39{L>trIRp!UGL&8B6XPem293N%0n*XuhhK-;v4G)8yV!{qA z!P~;r*e<6@$xQd|Pj*+)IZZV7=MPO^!sw*6?07#=6>;7(#?P1tiqvTH%ku7uL1*92 z!9<+;L+3HRP4|d0F@r z*CcP+7_qu#z!g$;Do6g0XZ6#3tfFhIYwW3A=V4_i7&h)0 zl7^u_6FY&N_XovNxvG{LRoAnw5~O=qZQOF4c+h$RAz_Ijg;wJ*IzB>LMrKKq4^N{cVTkK~TG-oJQ!ad4)GLDsO4a-U2qD@MG|8r%jY6xH~cju~)A` zy~DMpHTZY~hvxk9LyCwlE-r0m{Zcx|k*}wj+H^?FH003M$Cdz|^7I&>&Q&Kydb6i@ z5#-7stRKTf#Ax{2d$VyJZ>Wa`xK_#`k*_W zDXYf6{fme^>u@)7M{n>`G;!F;m)d#@^r)dqxsPIi<CFh2mLGKVY#Pp8NY+*<( z4}}e6fjOa=W)Ki_)Hr7hfBndC zH)dMuD#GVxEg0^Gg^^P(6;>FXjm4`k1rl<4a=*wb>{2k2p#H}cWUV{8 ziG+Pwyu2sc!s=qQY#yX^h?i ziljhG%7u$8g&aFVN7!&?aR0RIFAjJV)&OZ!DCUhf#aC~mjs?xHMueLE)u`4r0o~KG zBc<3Jw3}f$Z{dL+v-G=V!j&U0!@7Mjp@*Lkr1-*o-~xApwo0Y+EEz_uW% zPeVR;We*`s7cW&U++9hFC{JfBy_!}4!394TuQ0o`5L?~h4Ol@T`-54#8##4njg{W_ zN{Y1&$nnuM^%=7&r8OZh17_>FN)^evrpH&bO;SNN;fY#(zWg%xl-gS#Y5e4A5JvoU zkA(79X+v=b06*W`5hdwQBJW&Uie;67Jh@Rkfud#AtxxY#_=gglKU6{Sn0z~h_jz(_ z2d$Lsa9QHXbj%Hx&~^GVivziigU{Qr3P*EbX7<+e&RMV4$T^Pm8@xZzUMXp5F^r;? zVfdvNuegJ-G%y;<_h;M+FlWXAgd+54#|JjSx!>q*V-199%K5?pU12a>m?3{i<8 zgfM5sW1I&3Q1Gan^A{v~%#vJ+l8*C6^J~zB$G6}5?WgpWAuFT4rP9qCV*0n%-P+Ow zpMrx-hBG0qfU_d!J|F`&973#kZng>!xILd?`V4qEoKJELbbX@5j)N$u1MjRir+Khs z2wj5HaS%qEA$O=lD=xgPPZh$Y>jnNNyW5v$LLUGwOVJlTL zEYhynd9eEq3s#B0E=60v1(85qr;caPN~ZgalOGMTz+>M#zHNOOk78WcYJeI<*j=co zH|FFmHf82=&)MvkKk8YiCqozwNxjo=M@;B_iG-bR(|!kzdw6!Usem~`*$g3ALDn;i zBD&-Jjn~l;U=qy3I6oQ`pZ5$gdldi;rI9v@{`o?l5^C{LrD0Yay5@y6qqG0ey}Bk1 zQ!I=v2gKy=$n7U_Y-;ARa08+)R%m9@0pPs4C;*dXW^Di z0i^VPL3|l_AR#>PAN5@y0JD{%a|=O#(RQ6knkK*E)c|{o&OW{$j#oq18Bg*bV>{SJV<(>;=VqB$TP2GJiP>Pzi`5|JKm zDI#11Gli2taO;bi<}Zw5(fa8j+6N|Hkj&)2n|TivEzJP-jF=)rmoY}kF%_>3-Zr1=Gy+Pu^INOz$d3-?tKB9jdjOllbq+}jd^xCf3NAKr z&F@CHo6a<4fv^CDXA+-r4GNo}Is?eMZ9>Q6H?NfT&I2&#L(7NJj3q|IPpwrq(i&jY z#)5FaZdY|7m^Lgf*iCjK2nJuLL1Bb2K{NEjC!JF7hdA3i zi}UB7Sj{R)!}S zY4rhhTm5y7d2$pp=qWAcD=m5Hc8Spe03%vo_2StBHd(;WSbU-Sxfih--P2OG|B*Nx zeaVV^Jd|&w33l|@EmgrI%URVIv;kXTfKp9nt)(J`GYL~4 zIFayhjN@!`^Z+r_WgnsyFjQD#=kIKe8a=Ds1Z56vrGj-HJj<{68W)Skc3O_3#Ije1 zz3pcMF&U0w{A!AsgzNjAAFpf3Dh}BtR@2Swh6_nb_fTfSsAiPvyJEj*m5JOE^0J7f zFpSY;ibZ~opp@A{Y|U=sBNy8B)b`gu753hHb^UWZ@2wrak=c{fKuKIhSzI}%qNaTv zmmFmlDWgoE>irAYAiN>iWQ$i9N^KuyykrHWQ# z8pKv zV~xB_5N_7`Q4>9if$>|plSti0XF#gv&WXEF!1VCQ2+6=a>Kz!-)1tY(rTtN2rqwwE zBqIfZ{@Ww6=ITvLxJ6ERwhGjlXu-AQ(4NPIgO5n>5T7D(I`7KT@w=?Xo?_&PyGt9& zzTDFFHF?FI#vQ>KhVLNJ;|DoY=oJ)3gekgJ0HRpD(W>S|Xp;=4uoujoD^Az9mXAZ6 zeJf|-1#b>B`@D}#mI*3+p-`oII?#0kW=v63b*dZ-Mog` zuU3!+eZ$pjvJ5MrrZ`yt!vvgaJ&adN|0;7yXX2WRoH~rOlAYtjMU?H)zQ7mo z4ebv0hoX|vHycODj-4~Nh=66-sKI;tqDwVHPf7sKG@SbR*?_5Qlcy>K10W@IsV$dce zG&0dPSbI(hkkNyFtVG6C@gr+8)tK zjHfBS6STqHehuQ%gEL9*%JL+?3p56o6!Yrt(;bn9GaXb##5NP zhJ_ElA5-CW7NYT`tU8w&+!nl2qXBH^1kCstI|ocR!H6uI!N(Kts*}3d;k_nxKXk3*mwo(V|j$ zDJ#V$?oBW>3)Uxt)SRkv?D){}563RwzHaWpc-i<;V~#&{4>$_)bBls~@!w4PTw8!LI=Fpw0sFtPy<`uYavY(_sHrptw}sI*IhU?+E`+*wbwYA%FW9iF2m4 zRF5La9;H~5vZdZGf}x%*+4bHjF^d51nUzO+Fu>Oe!dsm;|0^KSI*k*<>q@x|bZiUW zGv9<|E@X2uxNf@fus>v92Tc!b6Nf)e*T~HUv5@+0qq|V*od-N8Okz@!4H!B^;_&cN z=;=wij`efHC~H1a>(Haoj9XVpqXw6xwMxwM)`D22?YTZl(QJ=c6y%1)S9lB4O+xi_Q5-PWvjiRq-U{6&(;BWExA?aUUJX z3^eXHZz!&UGYIfF6oK^~6!?Y&i;hZ`r|4{Fgz-r7-2rbqR8^ zs~4;q?RR$^LYO>&uNxXl9}Oxe3gl`$y;KVd_BGj98+s#D9aO7P<=vEl%ZugNb>0JY zeAy+9D_cd}z198NBE&v7Q1XVv*t*78ur0pZ6xx~(Lf~zRpeU~0#RBzGJ*|+!v0fec zM8U;dH3S$7&M2ont=&ff(37n9L^JHUSVMn4>?5HM_E{EyN=NabDGIe2WeycmnT9hPKJr}Tnv+)Jv8d*dQ@gNiP9jI~< z%Z(Wl|NhWn2bw-#d(wFJbIm{imJOGuV_EqTy#!8=OFHe4IDD6j+(XUtJL}m*FtTI) zvi0XdoVLm2xex_N0L7RXw;exd zZ_i8&ZVRN{_U$p?WS8<>gkt2P#%LBMfCvUs0R&iulrq}^r?FqnaM1pb_~oM5cA4X( z`EsC5z=KNWYWdQh0)9*;bIMmcphg@fen-!L^!)nSyP9Kx4>(tb)+kJHitP+e0{dAa zpbZs4sUk5Jtj`MQXKDo$UZ+o-ic4vv$tC|RsbvJYrg?F9{Df(NZ-70gQ9JU7RREr| zS|HwoJtxH{!}VGI`d&fl!@&FPkeZ7xVSqp%M3S0ECU=1v@_K+HCrF@rPJjiq74- zI7ik;r)oz7yr0~(;qHk}3SUvVdQQ)DXVQyM<&@GHO4;}&-G_iIb@sqbDX>QsQYqk% z*Oo=x7r0ANG1s%e-h?h+%}AsFtVx%~p@CQ6gx(`(5m1!LR+!iW(&yj{!tUA-NaZ!^ zeP-W-pEbh`bJ8!*y`SS8;I-uoYoH*5!ZD0^6+~j9 zg-A9&uBLXDg{N?VnEtv6EI^UJxccCUE29o7X-nW1HIdw;y#NdnH}NM<0SRDhpEW|A z35IaxGVE-q20-g!rrV8JZ+Xko9KH6G2$3{%_wt91NEy^(A!0)<$wapAK5O^HzPT^h zMlR4t@&v#3av^-Y&apC0XzjsU5-u=Q<8(#P-|V1Rk`l@*|h74t>SdYidS*C@H4qC#cL40 znyU+9t)h))bL>qWSg!SN^}SsCKy;ubz8(%b%#gOx+ezS;YG%1#Q<^09`QJn2<^lyrLRJcTnw&P}*`=gl0cyw69(X zei69aL)YallI%}5fR_#{>N7Nxs#_K}9EGX3$+0OH5M7uXATtpyrzKG@GE^xEFbY&| z5&htjin!%o1PO(#mw9(dla=gaz3c-|uw&JT3Txrl8@RtJH z`Ge?*V-4;SVO5ukC6$WPIEv=GZnj%fUdFB-v3s0g8grEHdj z!_<~dY`Z)|tw4S|$?djll5#EWqK?4wZ7kfcC!dqT;rW7?JeaBkqgBl8$`}~T`8842 zB0u0EHp(YdX_!ahwHYR~;aU++uZvGm7yf8Gi#{}BO-+}z=_kKNTNqb7@_2L z75gG0+aB$eZvn~QXgrZXui6#=rT0nw*sHmx#~2!6e_a}a?CaI^zH9nMLV4-Qdt*HT zTebPu9%LSfuR0|#@j9$E_=h`i1nVXq4}Tyz_?}%}ghzrNUp(chKqNlik@F*uoIteK zDzr>T85@62m?Ihtd3{$&2M*bjg%OYYr0yj?g11+WK7|nWF6pd60v63qn3aN4gRH>F z+c-?YgA90vRM$O#oGyDe6*RFDv|anPXbg8wqYJ+O z_59fOE5p=1`GrJgKNWOSGtp*I9;czXaN15QCqyi>ML6ODHpjF7m&j~s_tT$*&4Osk z=c_w1YEo;j14pFhXsHA(;|Ll-L9MTjDr=fKOEho^g4{oiO0nXb;ld?K?R&SqnC(XQ zN>4R3+|TEN-bv2x;XrG5myFtFS+E2IKXR51zFCF#J~NTjJ@8t#8! zjVRGxnqUTcgt#T)IBg)o`mZ`HgE-0=3gl?cIYk5Fw0Tw}G+ZVuSQlBU9)NXF(vB^d zzBi&66C+xsf{FBe$ODiv{2Sb8)+TV|T}?%RH)@wB(o7HX%mor)n@>mbem1n$(A!?T z@)lZf=RfcVjj$eqNT?`$p;q|AU(4O@QxZYaMdPT@BMk@U=zKkIxo~lEdY(K~sHPC`EVd{}oUZ(Ws0f zyVXe25N(1Jb7O|;oBkU-#oBiz1_JLoF5K46%DwE4OPlp2 z)432xR@R@DA*@EgD5%I^jdyFaN$?s6@QB@{@sxWGTzj|0%&z)Zu}sw(!uFjmUAE#0 z*6k)DSDlRNyCP@6Ya}sBv^9nQK`f8p*wNK)gmG51OTCHL$}DV`E9hr}^fe~$jVq_8 z)wZuqBU1~U<17t5HMd7io_}WhkzkchfZTpfM;kU~2u?~ka@QEz5&-RMqaJOW^R~vx zQVFgtwFV==hEy`oRx4N`64JbKbauV;{LZqAXk(gdk9&={P=Z5DOZTaJiH#&~0l=v4 z1Xija9a`<4Z&;6ng5C|dW~jnxR2GRMmOUmqy@OnG$>cZc%L*t@favU z7Q2Z4a7?$$cT%!@S6=(m9>6KYoL*m0J$ay7?~Q?NCr|F;KHI%tM4^+kqK@>@XJdIy z)#89L5MuX$?w;B<_j^Q=-x7=PTPa$@5pKh~#mXDdPIk>NL5)`W&0;Kh8N)sr1uXce zB~ux{>T~WGWV)J#`Cf2ha1mG~;JE19O7P(a=)74LH0!n+e@9M9&=&>G_oCE{Zm^x% zRI4Z)RFrh)DXMY^`^z2#1F%noeLlZ-Vr9Mpmdm9XQ#+YqU@K8ffuugRyI%42tHRbn zf;u9k?6g!2q*Njnd_GAi*6uvIfbV^Y?3eI+fzMwa^5}Y5YvcY*osC#~e>hf89mTm~ zAT5y2n=B%ZrXq=n)5W6Q7~xN4kwfRc5iV!pHryk_EfB?De9pi6yS5E0*6Bsc`@FQB zDmVg46IC?|RoafjvN!+%=UFK%O8_@O$iGr2T#lc$25jh!iDKvkA`o z47!>6*24Zi|796F_25%U#z9q=LA43|Im*x&m-;9?W(SxDB!fmivNaZ+jmHqelk#;p zLLhW(+c?@5$l%jl)(ero{r4fh;o+c2ul(P+V|waGrO@CV65DTN9Pw$T@lg*aIIxnm;)sISDinhjM;R^d-kju+Gh z8&OT-)!3)(p*jIw?dx?LYY@}xV!hImgLWe%hNHYXb1s0^)d{%jZG!o=p+`tWY@>~l z7~)fk+#SCP%I;=iZeE>;o|rhR6G7n>=7-GJuQy_DDml{uH!kF&ldN(@FSL$y%tNLx$lqr38#(kEl`-q-*OOrYJ-;JYGV&Kq zOqK66P{xQkRqrIPK8t(e#l;Akpl*&3>#`I4zv2Ce;@c$XcHN-3dXo|OzfLiHv}@aj zOP7lph4E`eO2yi>IVfmK^v*3j{o(43hNPGgNlm3?+uGSS_q#_SO9F)ljm>>D_?z7x z8Sh(G2E*HC6HXp3%%l{2{@XlYCC+*^3T|?$H<09X z?SY5^!TB=|Ac$56|5^*+>GwIc2EpDDplN^IT?U8~jzAMl7bCNhEOY)NGO5vJEF`pA zrE)Jq-C+h4j~%P5L1{~@Bev;T9w5c6G+SsrxKTHHLKSm^2x^9QEK zdsoOjXWfRpRHu)sOnE#qT6x{X@v_xd6(7wNuzb`#oRHT}fl0xTjzO4AiJc-$>g(w7 zVE;Jz;S;;=7z3qEA!zNk#o~Vh*83|rDQ;JwM#c;p5+WDZqY9&#y`$BNt$2u_Pe}_H zz4=sFO;nW^2vJIW5Y!v9f}T-O!1cC|!7(f0@F+Obv+4(+{~DBDVu{sjmk=hDFU!I7 z1ARoa_d42DlGdv;)5fN`LGdjb0SzI8x`*wvvoh9AsuT&ndUSp?8|MqTW*#)QJST9e z;aA5gdDESg7ak%pZQ+h)Mt`_C4t%AF2+A9CcwV_n*pR0lK*Hu=!ex}oM$tRKjM-2? z1c!4r@ak~|3V>WHj|n2jHNQvlfC_cP@%l=chdWI7YT@(ham^D4H;vurN6^Sjum*S5&S`(^4qV}wB?x0*?{`!X+wQ-lSta#a|M_jup!X%_vIrMoqhC?{gsq^+x z6}zD4DJ{CYqB1fj*UXWhYuK^%B`+Qg4NdYRwqh=&{&{PS5kVtvPXrx^C z4MxKJhmqzRCAJ}kDR_chycLqS z|KRDq%l}`ZYDhu9MDjKg;)m%?k+=Flx}kFWio!pvi4lTY2A*pdalggjbeE*u?B(go zYO9PADdR|T{Q9gGJCa@fBByy^%u9^X>v|90Ma*8kl2Shc{(dtM+41(oMOw<4-g241 z1GHuQHnUShr~p15Y; zO?dI3HiN<7M!Dx^?;Vg{?h>P0Wr{K}tfby|zjU=yjy!B6-;-AH$Sg)5>%BnP-9>^N zT}X!A;%t@)#tHm0NIP_Xw5Vf=35qGYbpdHiaH7dp!nbS9@0tMzD$s@AdkHq1nRBPx zm*Huve8zomxMvmk4AOoZyV2wDUc+y`G1U~)RE=IS&gJ>oocf}`hb?a+2)b@v2|U=E@)RymIoy99dGVeR!V>0F43aaam) zJD|`uwrVc#1uL?jWK6KV6A^rnlI4v=yy|(V%pn9lfGAni5R0#4Fe$Jl>TSN>Xi&3i z{m-h`cHNU>7&j_>k7?S$918s2pgXDo=aTDxbawArbI%2Y@(0A`SW=b8KZS<6FYn2T z5r;}YcpPR*pb*VT2GEsP$?phm%@Gn<)n+UQ&8!%chU;+ys!5aneMrIO!E}jfoKS@C z4;;LZ70!gaDu?X6VXwI=Y*Th0^-GW3j3dG~1@1p&GFL9njctS*VT@Gfi}w}t9e9^< z#;ZKOdWAQN?R54`i)n|8x8U6&o9QTC)MhxIOXXrX z%F>aibgMyD%Z%IS_HB#y02BAahPM8BOSsuUnS}n|iDFof<;evvFWJY{j=)hJuL2lP zLtx|lD=W)yyF$<5EGJ8#j-#F-Tq=vEmS!kBwT(*tY{e!hzFdN8(2fktNuqR|d(EW& zJpRHeKlES=1bBX?G&lvs9;FDdS*DPEG?Jqbs>NY1*-<;N?`Z&A zdfEWZQ7{mQVL55#w#VC=&IVFAI@cH|1 zziUY>e|n-c0{^r-)B3U#=Ngo0=RzBPR^5i^cc^E^Ef>*&5U?=D^JYd`-sSWSe+e8n z5BTn@dndBg+`?G^of$d@WJEND<))~N8@pit@OYucgE{B`$XxdAUM;JML}JI1I?`|u z+oTu)`_17k3UQ=_pD@Mn6K6uA_!n)`Zm&kCHqg?eyVqJnBO?`CzS~xlyKaiN1TVoU zO0I4p&dz^}HJJtaCv7vc8b$0mA0g^^su5zpb&@#<;=^NRd5TY&iHBiIMj)RS&z}!I ztTdqT6qybvjEmdVD?wwzchz9)yX`5?AQ_mGMI~%*%IXkT z#&nNmAT+-)4wi)3-)hmZspOEKA9<_&hIt6PK1=Z*yJWXcd^VM|4Bt02&hR$ z#=v#<<%oBcTbmtH4yqLej0(Y<1}W14&lg@{NI6{DH||T^97CjjE=r!`1uR7YYY9cL z^GQ|O@IS$Ly&6#LH?>nxfXerZ0)&1oYJ;`mxPR8^24X{MLj|M_<~6d<K3-?C z$B}P0_kVH1IqCUF1g~&Cy}^gg0QiPG^V{y&{Vj2$K_H72RTJz&eIiZ%!^!VDe2gvrDB@`Ja=T)fMmh)9spt1zWq@Cu05(uD2uw}S`Cc0ARzpyoGh^QTc zy%kUft3Sf@Utx&V6(?bN6i8|0VXp~(w9QTHj~iy`Q_)pQg8&3UTrh?JToK6BYEuRt z`T|B+Xo2Hnww>eudT69Muofrekcr=4w;9RUQ7FrN;@ zxbeh85v4z;Evc1R|4J8D|s1hTakyu}$EHr02t<&?%P|H3#9{w}$hh zE|St^h3E!c&RwjPIGFQ3CtG{x{b?B`ciRqVNqcKyg`ULYAs8F0hs`1y>j>w3ZG!>R z%*Blg9$Bq@UMcORbQ@hWKJl=m`_N8qF}XAfQt>yeR2rP=neU<&u$s+TZjPAk2~Hfw zY8FS@m?Q79f*>Q4+2+xX544)9IV@h~3MT1z-NyBF5$k z*K1s%Sxua+SSEp3)27gTDZww7i{xS3bEeG&mHT(vIsA!LT1ednC|{VWvUN)y4ff^X z1WMu%5O*hh-~#`lEvcm`vtto2m-w)&ogBnr>@pXQd>QQwOQ0`oAwj{2jrh4v&!H3S z0nv1Ur<&J~Sf}xF1qa5`i@RRjCtw+Q~Q5$|Ggf>>UQmZ^8w(Nvw@ zPE#dS1gGpR#bazY^JWQ5E{J-#(nYSy18w)#0MeCy2du;V5%f(&Bg__5r3y7w8Ku{x!Z>ANHaW zeWVL1T~qyyX^_{IF$+OR%KK>=Mmd%7kIcf9MBjUwpUY(8x3W?_lZW(^dMg`IBE5&U zl&?rV$8#k{k|x)^bT|^C_YGW??esw0_ic`as%dmTlF3@Vu=9vSXI5@a4{ppbx^7GKSM+u8^4@*_cB^+rM`kAYD4Gy znVZdx*(wuY(osWzU6^sOxK0NAQ1zko31+0el!6?1$xws?Y|Rj8UO4ac)qnx~9CW)1oUdeApf54qmUY2(JUX@@#bX`ycF zZb-H@KKU!QEZf$(gmrMl^4X3w6&`S390hC-GV(<9-aSTijaoy?e+2zDSi7d!W~>~9 z{p*Q<9K5RDq39^WlfqCB`P8OjNlMYoWNnIkROTkAdTzo=y2O0@l?I$KlaE`Ac;ozh zt22N7F0=AZA0AZ_I2(IZVXqOyYqpG4h`)Pzv??O@PR>dxcDv6nA#En-6*XO>{ z=f$3o>b($xH?mv23k1>bg-VlI>NM%mob!NSQO%$;T8& z+;@O6t>Ujx1t$xleCF2+r&w_#1ra-hGF?9&AX$!9(78W}LY7&5c$tuW_CCl3x?d^l zMTDTf;}FhlDl(6d$6Qan)|6%9(Js+JyRwVdQ}p+<|EGZ}@YV3<-p3;7aA5p!J_2de6VWgSw(vNPI z&I@DN(R_!6wYmlfw%C@(ciZvoMBH=TY+y)9fM2=3CAnn0Baz$l?Gud4s791ysxTIW zXN+ukKQm`M!g!~iE_oPS7K&V3rWsoMl+b*jgfvH>y8mVwBmO1Qh!b1lcWRl zR~r;*OTD4bV?qAKcX>ZWWzuS@oy1#TKjrTWZKR*XU0L73Q!h*EL0aD_{QbFD4OR-o zSs1aw4uHV)7fTG_ow;L|b^C#g`!Yz=0}v{w7|l$3l?{#2DNXFdW*S6daL#hu0VDfN zaS>P{^1c?z=Sy`fy#scnQm^(JhJ;H<$NMr(Ea!LBS!2ft#pQC(S!W6=WoT*sqj{{L z^-uUV6hGNaxMu_*tF5OI&i)6=n-si!ifX>0L?5-->R7&r+<$12%Iii=eZ~Nv^y|Bh z8GC7<)@;pj!TUFGuMEMI8+h7BMCna9cRLn*)T459w;2Jk5niW6@7LX*ug>dd47Q4706VIv1U|PB{2<>pf?@+M$t@~-3KElS?|D+H0jrISL z>hm$+RWWGjBnoF2<${i zWC<)x-BR+c3$H3uLCDH=SZ%*W!~%lcKoCOM!hm=n{S1b|@X;3ORNM~;lPy*Xv8R%J z7V}Q7;Z3qW*BKZqf%Ow0S=m2!%y5!@EGCbBX#WlEg*21wE@{wHE2pRVDhOs`HuxFK%@S(B0hsQtZ!n*N<7; zi!*c=Nv3w1C1jY3f~~dehIoj{@{QR6iW_lW!DK75gCMM?Bn&%1r566+O}K$g8ouP`O{u3e z@~zHo(_vk&WYY|S#g8x?tF!>9LTG=BJgfFxp?cM(G$UAX8}~O+wCeFqq*A8ufrDk0 zI6F!X5qEV-jU;Let9`M_>|g5lW~iRdmtw`|ITaRTWls4eTt6Iui8>KJiC7Cc8V=aI}`!zj0kUZPiujx;cXtcf;(5aPrT4yPBo1C`{1nb1j!kfGClY$>|( zVfJ-(uon$zeQ!)X7{DBB>ITZ>X)rgCetFw?TLNm_;v6@iosn7SGQ>A&y!J|5bpP-q zbhnvBA;nSX&IM4KsHnA)5c1+4DwG*}jI1TvD3}V(ARyG&XE}y=2a%)zkZ!J8*N^VE z_vBz#S2=ji#QlPPnZus9_ZV{hKToBCAk5hgpg{;4C@Sqg1$)lsvfb}wW$O)vWcdKG z^tP$=?Aqs4J;uqG%HD&_u051+g=f@omQAw=tyiekfjW0oDxgqvi?;ERp4M(@1X5Sg;+X=@!OJaA07-t&!`l4qjV3&iA5WjPn6AL(iKlz=Ad zmughnc^6JN_DRQ^wQR1F^%VODU1e9ZMnyTsR|Vh2&}>kiZLrlKYuC)nBxqQS`n3$$Eb$ zIw2>x2DLF~yOg9kf4|p|(}Mlm8wf{R>C7FsOM<*S@`tS;4ur}H^=7m#n~{|=%_&ub zD=3oPabt2{9G;5Rdiz*AXkvNu%{$`JDN66LXx3T0=k`VHjWibA+68QAI9#p4Zv!d* z#UtMH^xm1j*S((r67Yg_(W^kXrehY{_+?JQx()nu5v^OcASx@r@b;Hf4N5$urP=Fn zX=s|JccZEIFv@>Zl`*iThxO7Ocw+sRmHkZmI)bjp9lnkmTu?9yF;Ju8{iqneY0@#h zc=y|#$+l=ko(rZw5Ye~UQ%sa6(|8aszWyIi8(xrsjy`th+SA}sKxf)ED*vLt_w$t_ zrE{ho(2fuSxgej6|SGdDCH6vBPd{&Nq zadoqfrY;O%*NR+N99V>O6ef$hQstjZYDC5WM*PEeANw86O1Tn^?ZEV&XKgVYd5odo zZy_JuZy5lz)5av(sLtz8fU1I><&wrG8PU0rlAGO#^0OYXxC9)C?mWW|+rX1vS40Oh zk2{sW8p~xlE7+NOxhRd%$SL*)3p2}&qgQC8H&55Lddc_pKy!<=sDVE*SDO+WEs!IF z87+!EwbG@&_DT2CfG(po9S@OLakj4AmuL8lcw?}XJ4zhgcLyW0-o9xFOvcx9y#6XZ zc*}UJ>03TzJy>a4$H2bta_99og{W9|t1WiC@^u32!IIL1#BN_X_t*LzG~NR%d<>PGqlv>f=PU15VY*xbEQqEcT2`vM>qTS7=t$o zT&lVyAdf>buHCmT!pa?}M&Wrcr`w~mO~X=$FXedFtxL{LAr=F?sa zC((_D1zi>+eZs>slI*vyNXdOJEP?O{j0~b5c7TH^w%&y8&tM8DS7^~}>YpMk28Q;1 zLN*hEO@AfDhRkZep{D5QV`5OgIJ*_EHucysYv1u4-n6cLl02w$+=}ahYOS{~t3co6 zs~w^yk+{j|P2#kI3&Yk7q*W^Y&XBr=;$`AI`HUyZ?k!G|WLB9v z4!g@lT+~S2InTEPy`d4%j`7NolU+tq(=+Rt+!`YDCY(Y&Y4QhNmWBAV`WB^Jh7J~- zo6SWX%=I#`8SZ6##RNA3q;i%2hvGvwUP{G`O(Nn;u67X9ck(?B`TEC4+?UhjA`8Gh zu#eki+2#c=1C7hv7%`Q-z1vV{Olc6n40DcbfIC<@;v3Xb0byQRGVzw75Z>QeK~!wr z#uQ0ASDjH}_Ixp3=lUb3EXzHkF<}#uE1{KdZHtZ4j)Ya>wztneWRh*uk|`r|X9h7S+l4jofbvhv;SE4Uy?7A9k~Lct%hBBPCf#lt2SHot=l zMz{pZ3prb}=`vA;p<_y&D=TQka%o@F16}KGqUBtJS_kPA1aIRbVwYtbGP(e9YLHs; zI@W;dW)PaGJpcr*^I4HqUUqz01;l58N1XIvZT+z8_pqR9j)vT?P(yEUXD=Yc$T74i z&;OzwV#s=CV9_`0dRe6jyu490PIL8@n6Uq4@i+FryL=`9w7l4GAT9BD_;|Z3kZ|FB zKsT2;ORu^J6vuc+@X`hjWzOR^9?w)7oyFsos8e&Pg!uvUxV@o0S zO8nmgR>bmG*y?Ws>0l_3{(v;00(IFbq!ryFt|34hYfBec%oSR-Mc36;zbHjA4Zjw> zxNf&ij~Nvq%0lg=lamZV27}dJ3aXz4*TWxk8koX^c2T0d`7BJqo49e`vGh+sNj6Tt zmBbcomT`GzX=OgSe3#~LGG_BVd9c=pR#8oB-e!Px~+*w4K1hFN{+daeIh7nla{0M7;G<*YXD zYq~$P!zqUBlWz_6`W37B*m{et{a2@^&*~7fax95*X;!(dw1em)ICt_2-ug8d9puyI z6`VC8@D5r8VXh~%t6VwO@3_5PLO$@$=j?#BjL0^jH9M6JN9j6Or7|rFLK{{)CJ?+K zc|;JbFrcbKE5=9s@FZd+00tvaDLXj}CN^?n5%r-!5Lhd726+5s9gQ(v8ztLse9O8v z%CS6?qPU^ZW;j&?sg36dyEn_rXDF`D{XM%1-O<9-7K|7=DaLG-w1v2$;U8*IUab|8f69z zuVl3Q5cBqyne7@TeLcR>jXCE&$HfOuGNeIc40cR@gmzoLZ5q_yGtoM4@g1VlMi$p{ zMIh`(&5e?kG1|>G2 z8~_Af99V&ts1b7`W{3TUCK0_a2&%;PAPI}!B)q5L7VT>q0I|9$o8+kPv5-AFWn86U zqVAd$J%^&u{i!=XbviTM!w;H@EtHiPo8BF(1%5M%e+RC$#LP#bppugRW}zc`cw28f zq{jt=E9zCX{#~sl60}ryV>EhSd;$;U44lhM)Hwi<4HSSG#!2X})51jnYoo`V)17=n zBWC65L*O#qbcyykzIQD*KrZH0cz*sOn_8>fHgtrN>B+e9f>OOywJZQVCz8m#1Yn$h zvyOU zKiUF1$G;8R>qX+^!=t@3aENQ}8!PRhLUoai(AMV}lm9fpzt4w!Dj zK&kxKFDI!&Sh=-&1t(z2^#WeUs)zRFR=XaZ2DX#(4wtgGDN$OmHuy9ZpmgnCKGPfu zu%^Tw2#uG?yc%kWdc*I%>3~BX%wQ`!MZ?bwxf%`m6gDBm1T|H-nF+HUo)({7lC0Ry z&x5nSdOKtTxt112a=bGzn$_S9)|gpo&cu=K)Bo$5g$ne@pbs!#cU(_rC9q22z15KO zCl^O2^3ByBs_6HVu7$|VYoAyfBC2X^ICTfAyDW{LTtUi+7eu(OcKT5JgGAOE4Y}b! z173Wmi^E|~*Zg!iXu_;=8vibNZJu&&?#D9F5Ho+0k<%E-Tl)=ofIK90W%(y=a!TU- zSj)EM(7vJV_()(hY;^rt7+LCViN!7y!s7cg@WVioO-Vc-w(=`YYIJDF7oj%Lp=3S2fdAAr+_kj0YEDF*SBF#Z$!#)k zUnMTF7#BG<4pGa6^5brb5%V_z!0>$&ozC|nJ>%)FBZfe%AR}U*EEDdSf#H(g3 zu6Fr7ThQ8)lhFa9U<%4%+Ty23+-3){>Ya6sSx;0`N6l#{{wt(;=ofxd5!aIm*P0nR z@Z$sm?|RE&ULcx8F|)XX%Sz)fVoEpeUB*OUq_4ax07JhHTW%GgX5V)-I#z>4KAVOX`UnNaE31RN{{ z4a8;^xi6@bu|&kSPv`;CN5ZeGR4H}fBU!boIA#Q{LAzy8E^j!Pg^SU5@%)$-O$TFmO9>DG1f15>owR`+ zkxl6Qc{D70y{CUpj-NkpcA5(k7O+?0sv z_bBOtND{)nG6t{ryI=e_Cl6p6e|RP6(+@H!_0v_3fRjwkj1tOH#P>BZ-YoQR!)|AT zlcfJQxxbxF0juk@w~VQkfQoK}AbdcnPNNTwuDK~AC534KlzgA$LA;84Cz<_s!K#w~ zwa@*JMV~jLF>|CslbZe7a|0u{sq(w)b5gHb-HZ*d3?7*$8_+?e3I8eAu~W8R`T|Wc zmpm3YJPN_nKBtnV1-WSCX}Ih<559f-cTIMR40oNbHirZGE+u$es}^ zhe&S{Hg~rYM=}-toAe4zoaTXR@N^0x?*6Q$HXsu|twMX(gWEF+KCOezJVJYE?}}lU zz{$K7GkS`+2B?D?9AW7IshGQ=p)8RUki@gU{g$~K@qYa2g?AoqB+DfI6S38q#yN(B zn9}l9{zbl**E{i0ubdG^JL*CRlX^0-6%y-O0TnR1v@-dgkI!Ovxo*Yukv|}6^z8Yz zh4`JFWIAhJln@lp{rRCSJ(^Uhg7Hm0ly{-?kABZ?5bO-d72z(({~bz1D1)Dc8D=Z| zIjw?T%(qUnEAZ@Fer)ud=@CiJECP<4K!54KBXKw7?l%U9d_VG`j(O5B)u*8 zY)_zKO1?>uC;u30x1;~Xvi+=V*!UtP*YHDQGWwWivgv`3XA{6u3~zw%Z*E4*9pegx z?x2CdHhi$UJZC=Y`zkZl1k6$d^7M{<4Gj7$L}Gdqycd!2N7^LP$@UQ6&}TCz@6MuC zXBI{>t1QtVh_sYx{TkD;U^PJlqI9ffCu6(yNmkKSAsF7rI-=^9=PV^iMCjKMHUYkW z*g!H|S%y2w4=nq|R#=wVl(KhvrhU&?zWy7J1kz2IrbHBe$ixE$uS67d($NmnIiSf)xK5R6i zYhcd5Wb|x;#7Ss-HR5=<%MpOFWTkvF4Z&|MlDd*nMbek_#@Z6deld%%tF)#Y_ULnW*iGpx{8O**8tx{6fCgi8$LInL zQHcNGKV5A+9?dvzYm!B(yH4@Ri>hAaM}L;R4pnJVTScdtA7;2XTB(LG&|_J&(LWo_ z{~|O*?d;CCBS^+eF5))|kis>^HaG>$+@kS+JCQS_-~w#1zWe1)ou>m^@32Wl!4q8N^Z1mTxO zpc?RnuYvI8N9?o&G67D@!OoadR`k3zt8u$~hk*r(>pVvHC{~D)|BWA@{WU-$yk8pJ z?7sdG9qvD@4~ETs8cJIUa`*SX>;?q)myL5H?Yw{=KJLbprr)XWXGGasoZk#8#Zhd3 z%?`Oq@CirktX$cQ*i(1ojI&g-3*Fr$rX=*S4QRMgLm%?+Xg z+3fEEgPKZ*jkE@JZPtB5LqLsbg-wy7Zk%3JSPw+bdsB8$a1MtgC35R>~}wm}_CdAY3&Sx^6TF?iNyGQsUq z(E`-O!MpZ4e3C|wRnG^@)7ONS^b0KGKOT6-0^(`qUq&cH^F#U_I*lrCjYa9?jr5)Ul z8)pn@LAD6V5BGCXDChW-e!s98?<38Jti1A~m&Cjd)yGOm9yjlhUg|^}wyweymC49k zaWX$;QH3j?Hgd7^=5UoAB+=t{U;DT=W&Z&fq;MlO2(rtt?fPdo|4_8)X zfBqU^5BsjXp=bR75HI7h$>zlW{)&YMcY)`AV4WRB?*JSj zI+ftO2iT?Hd8!+jn%ChDbPj#voR6Qdzdq7SZ|=0JlLdXCb(rP9B~}~X^d+qVg%XO= zN5Lf%aGokl84k@<)lv{BAA4m-b&h4NgEjz~epkqVT$D{#Z#1SdY}53&Cov!p~k2_GdSzrnluG1jk@+wsR6EM0(oy!ZCwQCx*r&dxQf{4 zP3j-;`-G+o%R}aSbkI$apDFfN3<#_f&P*nur5DvG6);`$r0e zOWM*^d~V_2c^)=$fM>*9ZKa6;UG6UOw6`G5_RwL-g89H|FO8$Iu+7n1^%+1w9Bt^K z0}N0R@?Sd0e=nj{2`*O7Ww;wsYuVOIG3^|0GH^ggF8IamWudUfd&H`=O#t4JJ9kug z+qln58Nb3Y4o}cNWFolMdIZYvGm+g|Q0OW%m$@Y}NYYUIA@=VUx?9NrlVq;_! zbC0Uj_{&%8>3tG5FsZ-|Li}^-=NgIc&HaKEbhdVHBIi_i(=%UIz~BhsbvF2oY`~~M z?e}|#T~z>~PGYZv37r49?W_7gu;3{@{b~`lP+&!xysPD#4z{GIrC!Udx~` z%rQtN>?J@e5M~0 zMp7FDT~bMop=Pm4yDB*)1`UqIrN2&5-!Gzarzv{AHahNRk z`?wziV-FGjC2#Zr*kxh?68{2UD8Rh{K*x9;b^#c#rM1Q*X8Xbq@?%nJjL9 zhd)v4JX8M4VRB%|-yq8)Flo{CXwGgD!VS)n^vJSqK;2g*T$bW<_)GlvGJ{e9Xt6ov zp`xpJ4-EdtwjNQsZ#*$_>!M=TVhR{W7^%fw(Po|7Cvs7t@*tY{vGBuzwMP3qe1%sc z*(@~#RY`yWsGa=*jrowd#+u7!{cjhe=MA=&uk<)fSVOHjg!$NORr9Re^3!% zywh)7AI#HFQ6sXwi+upbY=b@&FMr0f9r{>@%CSFq9e8fpfWd+d*~id&;<%?#;jv_S z_F6$V7&4@Esp+$msI4lMY4!p*am}+m7|tlNL*sLd?)>@txba4{(f%FzH2nj9-5$nH zsi`}#R!Eq!{~VO6kCc7e#>1Z8Km+-T?BcSu36~k+O9Oi0>4Dd+LsoN+k9yyz?h~!P z*F;C98=_V;TeQAh-h633|hHq!-k z@LPb`&fP zC&CG87=vBPEwpzg+4L0PJ(F|%F^!Ffe+90DI1IY;3VL+8e}s_O6u-YDE}>oe%2pc? zKjr`E5cZGxQll{`4$?Ft^d%hWhPzFcB1$WVLF+se^}Hr}r zInNm8*;P_cFG)#dZ%2G0hlPEf4hj)C>`wr9{wH=AcE~*r$JI~=dVZfVc1T@MvuPjK zislP_Ge#0c&F=}yXI`W%7#%C29+z8+0#t7u=JN`DP@r-?k}~;v(xRtpgUv>o!~zSq zg*3#FHl$z4aiYR^3t!kxm(>v*^*f%7j+cQTP3AfApr@@}_;0I7m`zp5xUA^U1w_8#Yv9=;g2Wff=k1+<>f06IM6+R7?Ia#) zt0~2iYqv>nmOl?YlmgINM`N6wkPTAI4|^F5+)7sCqJBMn+!Z`RKlewF__I{EBS|y+ zPdTa;P^hk|kvmj2nODBM@uFxg)vq5~{zU(sO9>c~ILJtj4uG4tlSVrSTktc42Mh8f zqR2b`uzLUwfa)MqMNkAD%YZ>S;HxG7QGN?k9%BRf!sf0B;AxMO611JIc-GtIQ0Ctz z39%BTL*$2jp^4LSA~MBr!FyoLtVaUPS04pYul=fDd%)fSC8MdIO9?f*(>USKXU=fg z)Y_OOsRtrjz$+^_H|ckNGCV<_lqsA7HezG^jkj7z83|6&eiR_;GKMeqcJ~l3N*K~; z>}gWcTJPsGXg0z%_OYf~i;SHME=FMI#$PNu%5%NiA^;XKhyfVPLmA_(O8d%7ftK*B z+bkUBl=F0X34`g005-^TRzMCh=*{FSQKUP8PKDoxW~#wEpiQ&kGQ$BE&q!xO6dR=j z-X5?as7Q|dUIbTc#PCf($Y8woI&7gSitmwVny0+>LYGSY=#hi9YNqfdU zgEwD7I~p7aU6EDg1?iH2u7!m$Dwm2K>&Hj%mZF*&V!}r2$B%xv;sWjr;Z#vrW}?&I zMtRD#mU_`-c{YOenew-riU@z2hrV`szVOY<=UDuqJ1Qw``fXwR);V3#0IAn2V7dkO zVbE6#7}T9-dHg%{5=p(iH~2SBeCdizi}g-6KWO%*_3c`k%5L(%y@E@i#xkRU{Cy6H zG*Q-e=LZ!)Yd~aVY9#SnyroKeqPcZxNRaHIgDuj#23w!i$z0FmcOca|~XG_U^+CIxz^lB)Yd5){*!Fbt-9arDo z3@=fYFIE#p(!F%#Jz@}NQ8XMjkcV(JQ8M7(W%ZC2dPw{S!)FGvBbIGR?Ee_SjiP8Q z3E1|_{k$#G3U<_1ZZ!h$u7zXsoxL5u3H1|S)$nNly~c{kEhn%pcS4{hE1(<^M)whN zM6GFDhc;J`G8n2Sx=yc3RYMK<^Q#W4Ap@JkwKjGF>Qh*^B8Yg$fB*K6EoTXJX)gBa zd^-v*+ur|fl>i4dVBr*o96xiAmW#M?E#i+Hs#Y#USSVQpu5#}cJDqvBg#pLQWAtt# zEJWOE*>Bks3I|yr$R3syy)@c@qLdqu{`)5M*jBDae;p$B=$a)z=t7XZ{!%ZkCtZ>c zDn^VTL`sWGfx=Ft?o4}cem;Mm{r4{aBwh;N^W;1uJN{{FN2FE>H&K74Qp;9>v~q9y z`*hA~gH6#1*!lM$_IvS7<_-PW9sgHDu%|cE`%^{y_Ri(wU<8jNP4t8tWpf0I{E;2eORP-;?O(z!4EIuS^l#4XP;{q0X0>dE%Wjaw9lq z$2K@q2|eS-Kla>F)FS>wvw1>H%y+d@o?3ve5BNJzd2dPL`k$VXG}KEy=foHndt`Ae z5o$*N9LZko^R>oL*uO;LZ6rJTUcp!ssu*O`mKhqCOcMK(i0cy;Agy@PA|9q(&cHi`fQ25xG!{>ysD3AA5QgL z#R>i7Yj~7a7)vsSsOTU`vsD2ZJ~@Uj*f3+zkYz2{8efEkdKgUGj4z5z!G&=+?Quom z^l!l~r=bBq!2T z=o}Z-1MJ2}XKoAlxUICG?jwQ|%DjC5c?+7S3~S$bya2N%cHykWw`=0btP&D&S9b#M zDyKT!yBy&dIWmW9<3Gp5J2Y#a-A(jPSct|AEaJr>@BleL#=k&gYfyd0q_Ppu#DrH~ z`=g$_-S(s!Q?u(*JBpK#v1^&BRo=N@Jf_H)wm^n~MlSHIKcPkd+`aCjJ&U(i&)jRb z9{H_o=@&{VMOJzo{*rR;ed0v}5rKsAFiEhhcPnshjtJ`=3S^NKJgjdKB~6A$@Jr+D zCj1b_a9IB^=}lJg?X_B+X(#pmT=Ai#9JV)2PPSDn0jNZ%1U&jZXjz>Y^V3WxW5D?) zSoWU^jniws+vMhrP)J3GNpG-dc*f=#MJ5o%?OiL*1x(?Yso4)MWJ*ZLryf?yrR}G$ zg`-1!dZgtYBx*RmdTW3BuMV&Ytm^LKr9yd;%q-{D-{g)TJnvU-MaD;^A4*{l;b__*8Yrx=yMAZ>~|@36&ms2C;U#zj49|s<3ad!Jh-W zFjKZFGo6rduOv6sxf(V)L+S%(xtOgQI|U5ZCvhRIeDxx*>1+Ah8C> zXIK&o1k97I`Og?r0vq>_@ZKC0n+@_HW1YD$_s?sA%C?kl^HixM-ZPnr+d)c@XW5j4 zq+Y{ygfG^wL^aZaxk*aG8riWlKF9taT2k^q_!zeONZUh#U%k&$c`TuW4XLXDNy7xI zcK|P}y#79iuDvn}0~&`MBQe{kb+2V&N&k1vJ14AVVhMuh7E!H)&K`8D9qx_)QKEpA z(S?`?;N_V{Uk3Mjq(F2fdbu=@yTAIcJ&0g9R-Ik1q19 zOC@=6m^kbhPGil-Y;k*(3S?-8y5Z-B<-`D@kD@ramb{*R)i%Ah(X47J2BVgR^6D1e zC5PVQ)I3uIk7RbPCn2A znlVVkDT;7?CO4>nl5(^K$^MuG|bzbD8n;gacmP*~BnSLE4S_ zw@V2P7)~&{=)&{z`dGjVRKKtXhZVU1@gSVE`(46kmg!#G7}t~qswKU~P%{vD`*jhv za4m$&Q`Vw7VYvuw8_s?9B1vcFD5r2>hyu;#JPbG6Km6L@$gqZ_7h?bcl=)sdUGML) z5bVXor9=ZtNAego7Gf_)NQpftDz7n131E2#GfR#22ImnJph?v%K?0+F!z%e9I^k~| zfF>QSxB!rZ%DsXLs@l;4hx9_m7Kic(svL^orN?h_CC^6-E9~j5U^%151v`=-CHb%# zI8X(;KG~-a&tDpJRhFa0pxGKKNdQj#T2hu{h&tVYw(GDb6zI-SyXN@nlmTuvg{L4t zfUIRa*n zqs=EaL zMoP^a^`xEekz^OwK`GMd=c{3Q^MMj}t(qQ|4CJXUP}x%DzJdw1tVod_5B)0E5@6nUa9I=*D_Yh`SyF^FGM29Cdh zxh_7@7{`4fz9HE)z(Y}h6-s(qwx-_R=ZVoY&y3V0P6HhKQmxiM8ouzMv)|kn1j7Wv zU=z`;>szC2JPHcwM={$nA%S-ntXVV3yTYE3cC$XllUr06bFre*g~ZX>F4I0sEq776 z2z9~lnnl8wvq%@`^|s7$M1Fb^<8(EFBJM*VY5b2tt9CYaFkqtwq2D(K)CoE7GG#ED z(!jXA!77`8UUj>jGDa5G@0(b~busqlqu+X>%Y8Kdp_KyWmAmHrf!!JEkX#Uw6y@Rb zCZ#ozmI!YSVzyYG5rEvV2S}xVGW>D5SU6JsCscFzYeLw)l zW_wOEPf79AhzU_{2|TixEt3Maddr`%Ok(fUo1nm?ni{iaCTZAQRG#Nqr^#Rv3IZMI zr{nq=8UlHfuqwC3i3bO+Xz)#Od3)S<*uVFi;%Qv+idWVLC>q8fBt3yr8D|C4nG{10 zn|9}7COPqT4VKa89&Bm&&-iW8=EYL{N5OC_wj%L?H5RyQ6B~!UmIUiaO@fuG%6T-4N+6^cXsuE(dp9ZPmHj3%cEX^7fnGSsHDy$C zm|S`{!;40Rm5$Zfjch&ByfZQ-Ss6`uI<~l_7~YXKkJR+|B9Hqoz|`@CM;Ww65&fc zIQ_E%PGDC!Er(C2OPnf$0H83?EN3yUnrc5-ciFF4AiTH0yn?f}dx z1%$-tdwhcPd%o^jrRYPlYjTm&8V6mcBnH=U9r^*rMVnFu4a77?a9dxKgw zA;&4Z5$VdyuS98LQfJ*euZF468xqJi4#a#>(KqUO=P!zi*A;-Q=z+h%MQyusWI}J8 z0&FZ!pjvksORP1a=^4se)-OoQJZ0{JI8QyOwUfdK~;rxCNZ@-`q7=?x^ZF4RUI za0z>oc@L6UJMDx$I|aGYxb8;}iUeU3Hb7R#q``(5s1s#;`<{d-6?2T;4}Q}bKWijo_0s?xKGSvwEe$WHwD!(F z!T>JL7#%nc2+OWE5GldchtFUu-#i6q*=*b|qam^>#^l0~?X+!DhvpE^{gl8}Gk zmS(-eO@{}vN)|R=F8&vVADTO@zoic1o@?r&xH}wN*1O)}uc~+9*iCO`xuZPUAX?FqbtS;ErKs3>CG;|Rb`9!K8$P>DvN`jz>p^MQA8jSVpYXo979Tz9(V3h$eptu=IW+x2v|5~Z+( zb*evB(9M_LyL&aN<-~TvwE7pnv=^lP|7oM`^<#5pm_K1~P{Qjp+?((WiWf*~NPgr% z>xSDFn;&(BL8E@>PyY_G0O!0Gudpt8{Ej-CYIJRw1c;#;td4`YxmFabzwmHMI_2}k ztvp)aizFU6f{8vmgd>DbzNLg$&{g)%=8$?B$#$eCP~DBdj^cs(GD z2?FhZE9#js^VSS50byV9_>Gc<8ks`dbUDs~Rz>OSQ6!->1u0x|FtDZ*{-bsrg0hA= z8;H}P9Z$GsYZ@$KK4ux<-4O7(L1P9|p=B_z)}c+&hTgK7gTjCl{Z&wIA3kX1&&@)B z^ZBNP=*e79cI*_DXTlsH7FPpZRzXxGe3@AUFynYoT0uiILwU&G3r}?)!3MAMdOb^PKugL>gcDMLm?PLGXddBnc8 zMQD=jw>zcXPjN2Be9OX)mr&zH*|c_)cl8kB5Rjfzw~L{)3KEG?x72C3R@6x{2)xfe zzYB#W3QARC78%~^@!Z)DBwJAg(Fkjxb_XIgF_)+qQv|4{>S8)Ng$Oyi;9mLzuW7ei zhc|M?r76K2kKd|@E2=-th|)QpmlQF5?(D=<1AY`O(fp(hD)2nxTDS-1D2}Uet&0&r z=@L$_kU;FGpWZXsD|Q3uIW0)w%ZLdyi5vYW7U61O5r}40sEXC@^h7;7-}vwb7PiH^;h2G7t3MRIu>TCzi!Z@%Njl}H9duiS2aU{T8JIvZWf~G!S!-GQ1fYc2B1MUO zL48=@)_Uh0zz_r%#6l?F-O05^sL0%L4jzpCPh!`bb+@gXU@_~BKF$H8vg!7B{9O*Ylce4~ zW}ml9nn(XTV6^n4otQb|;SO>G+}(zZH7}qu&HwN2YN{G2W&C+42JHhP1F>lCU3-0) z6x{0*`fQ_hioXjUa(#N-$Md+z1=HsU&OnoN=M32!6v{)YKjqf^h)pn^eZ9uSD>xru zYX$p6b?7{nrv(KGkbd%}C3tf?_+O>xLBf<4sl^^VF@$405I0~}f>|zgB#wpc0mWiO zyqQL1`}$==n*UQVoV_F2sY4a8n7>Asr`1af6`&7}ma>c{F#E0+Mp4Qd1+*yOPN!Ei zAk0DEF~n}BpkcG(^rSr2zejgE2ekQ7e0^sbCd0P3DiX>=ch+$*HK~`rEBVtlNk|6j zCz;deN~1@LJk)pQ8Oi5TLtYOx4>$!82`e+|IOx1l!kbat`O4f@qTYlDs(U4`#EHTH zvA;`Ah)M+-jG(ogKV8YuYg;>jYxquOIdOi7s8=HyfOy^q8$kSVZ!fVq-a9BZc@9WP zs)N$K8P4eWo&fhZSIfJ9;9?3luC2;KMk$IX;sM<^NIMj7vv*I{gSE(e2p#rK;GN9+fjNDLGNHwb};i=b_WV6u~fT(Kko>>a3qKb{51!PkDs5(X~zG_ zULvw%5tkD}8aTTg-P{~cAHYXz1t~I&2Ns8K=LkTxtLgepaCDeCvK`~f74|Tr0ije; zM!FhDsrxWVU5*$4PH1>BO&z%VSGsEm(kcGaUI_xUHQiSBbE-BZC@^p52ZY&P@zvk0 ziac&Rz2ux_qWkm0wBDZ6|1K4P)TBq_N+adeV#CFv3)RR@$@MbzPQ{dB|ir4FoFcEL~ zG>{ymfbwZ(PaWT|NY<2>V$MtgPZ{K)?q8G~c9Y-Fky(C7L`$OO~JpZ{Q(4MjR` zQJ%ci>)FQvUuWgiAiM@W09~4LvZF0g^NN~{E<|%D(4McpMDKh^9E$Uv#4?sXkoBz@GV$7P}c85rt z%HVVZP4je04t=KMa{ViNpVktk&Mkak3p(l6gX@ejZimUi4%t34pq^8p`x#ki4IY%Z zwmUxf8BlxvA(L~nHJx@*UuDyM+Tc+_K>CDR=hC1~Rsqi;C|`z_y3mtAQ!t}aE}{}d zS`$MKkBtY^d<<~wR41!-HajV8unN48gAP}0e&C2lYPGPpGWI-zKHPl%!W}h(2W6X| zrlw9)4#pi6J520y*WbXJXy%)e+WowV+b`M7$ssta-JO?^aDGTO5Dh?+y*88hZD%7& z&>S+M?4&P6)Cc%LZq4Dd|2s@+$I^nAl-xGdx|~IgwlK+i$rLP3pH)28yxZk+L$xBh zxPRuw=icU5q!#uxBMwJ*VaTAIZ6C);Oii8&KA-jGb@kQfe(v+x*X}asmjQjC)&jn} zoC-1ecHK$`$!0zhcAVN`L_UN+vA65`Pzy4+3r9#*icxt%6@0pdx3x!&;0j|)dH{Tr zopx|tYux4e2N|-XY2JWI+a#r9ap?hQxKHFH%9bmr8q3BpoRjyIDf8|aI>95hD+5)k zKnlc)LP84J(khoU@}t#cbY}Z4SZ+H?IpN^3Kn9)zFrU?DBQq|Ab>I_S=@ttPG?AM$ zNL-tMq%TkHVg^`nREb@j~f1@ChbHu zLL-{c#q}^)jokEWY`*fQyL$M4TQMz8(q>+VSi&9*>>(6cC>ErP?s`ptb(oBKi+R5Y z<~O2A92mWdWbvma2NSgJ=mjY4qh0FJ2E9 zrbY9Tfpy;^b;k!yp*L|UMPs_~fSsehaU-j#{EghY>np~V^<4_2740wo;nL{OM1Et@ zpP?OV)<&6YSay`AcxXFVCLP(uTop5WU`~9Y9Jfm=z3XJpXkW>gGKky|rInVord&rh zP(c=x$#4yIlFMTH#-fbbogwJ^tbO31hk^W$*#!x8K-)1p=C^p#_|}}cQ@D$$RieK^ z(cYSxTauf4+l++$PH`bvnQge<&f8|ph}gK(PL4T;JzhygV#K(;(WXp7iG zuegH#RRKo}{)%Yp$jWuV!4iWG56RWi#{=LZDIBJj)7~+Xio^{l3v`Ne(gx$4+V}q) zQ(=OPN$|S5Vy&|*vu3{dqNYW+fn95g@x{&Yj1OoP@NAGiL6R;GQLQC`f*iWDo*b3M zdj~2tn5OkQ)Et^3?(m|$57fr3Nq_vNxV@+gNZ19rLBYT3_B+MWPNObQ+z5GO5tW9@ zC6zFxc8ydRBhhsKX&EHmuXX234c=SH+?R7<9sTvKvmVOo5_q4vjwt4%^9k}w$QmwH zEV%;@s+eG;|C(rj-p%-^pQY3G0YBa5Use0tU{A-})~p&zCl<_B^REt36{(leP9o5_ ztO4ojp78Yr#aS-WA+aOQjK?dr(-HYooc{W0blY_V%Oa7UMiSUq5d7kV%YI|q34o>8 zfF>-`q+f!i^=rDaIH-qo{;TF-kxe_+1{}=6a2V&Ma^(0hi*AA6vLh+B2ERT^A1|KB zO<`($w>fQah~DeI9(|^m0@RC>i5ac}c9jy^m=9~XQ@xJ&!gELZ&@CbtL7))zCafmH z&J6z&9R8K+*x86;jB@n;C0l-_xRdhc-Jb7T6~@XZ5>LIC7bhiu z++A<8D*#gjhtIMUB5{DTm&c>n8ccy#NMFFC&m3yi1YL|dSnW~IZ&!&y6@MdDH>!6E zXl8x-BpAcqKPssz!?HkCHHZ%jpGGE>4Q|rW1q5;G|H$ezB*Fw;%hXP$EU#xD2-NKY zSGSGqL~NjqE#gF??5o&WxyVX(!9Ne#Rl4b`({=XN&&WZcRG5hT_oG|IO42L7_&dqF z70!9s8?+%vaZ3=35fm*Y{d@a0@sTTgoWzQ8yHKwu{x(%o%Bf*+yaI|_hU?&+^3J5G zdS^s|UqZmykOA?mX*QeVbCkG@D+2ogV{t%3=5MlMK-^`iy}O9rbyTswhy%H-(WI7N z+A<%Q1rzcqOPF+#Hw4Ra^ND>n8b+(2viwdgW#tF-Ih+u%Z6iN`G{z7hrWT^fXF}k*rylJ*tWUR+?4HZ_K{F zccvGk%6v(ds@>IbwhA+9ZO_};49);P{(@XZgb69+Sl@3)pWVlsX5^c+KO9n=X|t-} z>YgPRPvQD^m)#5F5gzZyVxtJ?C02X4nZoA|McwG!x>2|uMeVELRfIFjBz=l;L(}D6 zk`7&BSE|my!tPSi{*PoV=!#l;MNGT!TpS?>-DGcda3^clA3Ym+%&voA<-Q!n_ohCHqnurSh#D#B01eTZ zYoGOD+D*1bU#_Tw;@R`zUM^T0e!8Z=2`MR8#ktRIP*o-++Evg)V53UmeW77l7d7^$ zIKmI_NDtq|xWXP}ZXsWywlnNwh(RT^4lA+T7oqnL+JmLCMO$T%ba#@1FC17>9`hJx zo%H#lGiYkPp#$oYKKJu?vmf~;@5h9JZO&Q5Iz}`=h0B?<#dva$Lok#KJMtNKk2U@i zgR!MjvYBMXik1=|Eq^>BUe>LgHv#guUMF2LYP4n|HoP5W{wqO#A@;NO3yXBRm+u;z z3a`HLY7N=?>+L=6&V3#P`&Fb$!Bhzrp`GQ~zFJNacl^Jhiy5K}hR>v$Klj}q6Ty>%ZHMu6^bKDxu!uX-}-}UxzCr?8xI!7!k6Uy z)8lew2O{%MpT6w8<3qDKClV+kehRTqKnm2eykR{f|HMmDz+<3K9M+4}Vm-&GI#UBp zzp{{=(<=*ey`G*Rm+LOrqU>RXDmJF_t+iv(RwitS)TX#lyDBd+g~2v?CdIPBL#K;y zpz0tRH%;k9SR_N5HDYSUeJmX=0abyUY|Myhk?}>3m3^(O=sbB7!dR#&u~e703H?9g z0w322;pRdb@J$Pr*C4sx+Zi4l*awFZW0PT4GYWHM+~Lr}VJjVkTB;eZj1i`bzd$mq z+KD%cZf;P-r!pJLkE2`Smep{&_-ot)dMJ>6e@{xd{DHWZ(1A9J1aRSVw|L`YT2^Q+ zDI%WnaF;to$0d*R!n)mWa-eKc+NC=S42&eHUIbJNEhfp3DF1hnm#P{}z$E#bG)!b5fpgifb=fW#;VtQGypJn7 z6GI(&dq;iMN1n@upDj&BIzes_LB>I6_n~j>(sZ+Vb1LNIEQk*}ccKAS0JtFOFv3L2 z;&+#{AW9n)PEx^AAjT*wk< zQO!S>DZ&!n2tzpEQ7peZ=M~T8{1MeqLMI>Mn>#L5@pV_COFsYT#Vz5vi&7B{(5Mmb zkuR1byo#34wBE!S4E6jZ956RLCweP_iVwZEtf!aNnmN&z0zN-~X))kt?>*c3Q<1xl-1f2ATNtc*65+sGw{OIJ1g zZLrGU1b8dpQr7+TjV;ve9YCeLww_f+TTf+I^WGS_B)DNan2$>T7$psJBT1xHFhr#e zIP@-WqF44UkEgCpVp4Lm7~xY zUaZdb#4zn$7_VHaMcn@qHv zRUeG%F%oC}4I zeRz75QRq3C*_yUlKC>V$Su}{vG}QLVvR-sha3@dfH&~P1YcR0>i=@&lb7yHOmBgfO z4tog0GFR-Zfo+JuKR^N{n1WWc2O(x{q%%Esx$mq|0AzF$=7e|@MvWk-`Ez;+Bx10o zDfG+?6dbF0P)2OgbSHW1+WrpLN}OC*(I>()bU_pV8y7v__qdbi4(^KjoG${JGKoc+wYbW=A=iwU95)Yio zIcds_9@%wJNNv`^#IxAX>3co$2}_e37!zjJ;2-S3jng^*hXSJ$z5uC{>rNFYqvaq5 z=Ax`l3a%%uYHIYMl)EP8FA)eVG;|bb)O!6_+|rDG;yD$f%EeV7lb~?;tn5RR&Nf{4 zA^D3Ijkv)EY!->Mg1%<4d`{U+6E-qM2|J9q`oI)D=jV@nFPWnW|Ibk>=tccj>BV!V zLhgwfzmph6?)=cr!OvwjvnSqemb&l?X;u+Zo19G8c1@P| zB}=5+&VHW9hnlw`OxgFSktA_`7`7HONw&6!(eav&%Sn)GfK&^i*sAo#Ngygo6w%Vh z(G|+RGM&?_Deh}9(O@?4Pjuzc26HE#*^?Om(p~b9Ns0DxzQ~Ji<58K|k7-`V!lw)_ z&dx%RI3$=mXrf_&#{hEs4FY$2=w)QRjR@6?zz1`U_*F7_L3lpK2(~G+9dYrgBZLTK zv3f~E6V@3ZR(*x}OWW122Ra@~C#c<9l^DaiDALV^JF?EwZ>rqiNX~}>>Z1Qu4RO&i z6t(nVuT+&n&Tr>bQMzYgi7sMBDmL<=7W2>gyY4(Xqj?l8fPzy37e{ON%Y*nD*Z>Ja zK=FGe<^@-^jDDXMzDn$SV^$ zP=sgEsF6O~@k>Ziu?!zJBx!jAi=E-2|;y4DB_G0Ju&@i6z zVh6FIw-xJ)AzIG`2;6pZ-J^O?lUv4S&FF3x|Zg?AyKG~d_)PQOfj;3m1K<%Duf_jT9J<6m+#261P33I|9oiQ@}xDTxWtb_*b z9XR6}RKf(+W2tBpO{nMd&zn-^ekMFgV2U#B+t%nc2nFI~Sh7S8%usyfK9%sLkeDDjBRXlnE80O{p$JUY$6h0RVh@`(l5--1-cd%Re4}HLoRK^@}KfTC?=1`7v zBb1|Wq(`^puerFPwp$1Gs>`tQsu@zf8;gnGyKXY8Q|b}4E*8Co9vsRMZR`r$Ob@JA zL4|cpZkQ61>eWOmgsKSF)fh?_j%{`6*cV71X(GbFpmsq2(ZUGzDc`8MOLHjsauw^) zfY*BZI}5t5o@$vy=YI&E9oRpw9J9ZD$BeB#SWKN9lt@aiMZ5jx!}4Z>V96_F4s(i0 zwRDt*3wi0p8vT3V{NHHt*V=_mo$Z8{vJ!N| zLrKyvthnF`sDtfU$%_^%r{SVmi(h^(0gm?$Ec#q6O(Kwt*y#iiM|8!EcNc7tl9SxBMhP~|QT`xTXPq6A+XCg1djcFP zYcV~d?o}YPW0w3XT$=6s(?)(i7r@e(9r&5@L$6jgj5u`oq5Mj3)u)HKt4^qL-2O_3 zU4>_pxp@v1v&GgR2t$Ot5M4?lXdejz(4+Q1b%UjUkM2Xz!#Nn5&5Da(Een6G$cw+O z$C2@6j>Fzp5w+ADDoXyR7|#b4Et*@t?trxzFkb~ANZSyoz96lqqChy$9`|SG8YblA zw|o7Q3uIDV!i3gZM&js6!z6VSI_w%VzcTGe>%9M;q7N%SZpX+K`YZW(>Gdnd%<}TJ zh<9i)C_9HO%iJXLx~;!Ve(Q3%&^wN+_YFc$=~llWgfRF~DxX=!})d38?Elzfh z{9+S@>ApZ91iwOp!nbBt+Jk({iZ*Q;1sNoiT{IH?65I+wIo_&rZvlzR=a&|;)-@b7 zm1B<&%Yc5!@NZ?IQ*7?k@7LM3Mj~}K-hbG6!X$Jo`)A?ImE@BT^!4h+WO$V5lB)FM z6ps?J2u9NN3`q{_%Mna4xYZ_^X+AJ8sAwR80kO1c^h!AG=le=K3H1nsWfy~9cpYOu zAM`O>tMjF{IEK}{JlnNR^V!oq4Al?gRxR(COk)!9Tf`dtPsgD#`euYIyK-~R-?+W1 z?84P$sfHXS-Q@nX5VCh254v2!#RuN6g%`oH_Uv$UK?I%rrLhMrl9OS6{9M+4s4YlhdBvFI0Y57YdVq&6V zHVGRp9IUGx#Gje8d7JN0)oY`y%yITW51i%)4?-ZOh|%a&KNPfM7g4zs7U}D>wup0} zB<^MomoCKF1}=OOEGcH)51pLlsyf*sU?bpbg)pwI^p9+!ullXa+PFSPL9TP@9(g=ck6#G-z}o({J#?SlvSdB1311cWIOTAx%mJSNI`$Vp(U9 z&8U)|VtvgEaoOAmM4r`9Lnm0DG&yk++=Dz58INd3arf|VW1CMi1GL-}8Z4xK&z)_a z+1*j;_$dlTW{IZJ3Z_b4iAE@#6W#f17Jw|kxgV)>rlntjoiH|ae}o)+L2miUGaIX@ zt=+31t2s1z(crVw&d<@nn_tjCTGFj4v=4oz`S1zUX zN_Qo4RG!>30b^J%#c*Y&Vb))%*J$$CRRsf zwak5o+j{EFH3hCK)dEm#e3tc50q*AF#QUr3I-={}~1d z!j>x_Pr_npx%{FRJH@}3Yf*=PNs4?Cno}i?ds}Tj^8|I2JGOe?vzv=`oy5CQ?6sv* zk?H^+@!eUc0cB$P*3RZyqX2c^a=#lW!^RqoI{Fu6atYr-Lr*CVmFb&dMXpHNM$BG^ z@AYyVf3quOio)CIxx&)UQHRL}gKq24*0u#quLR<`dfZO}aBTA?{O1(EOjn0=J&RDv zuQc+4P&$fgS4PCcbOvP;+~Md?jOgm5l$@;0wg;ow`THu}a;R_HO%{38b99pP3~hun z&l*lE_7yEUQY@3=#scB97lDs5*_P6@|XFRo2852_(l-3PTK(mKU^1T;%6mZq=hIu}H zemAf}9fe>OtJ6pd^yhVag>@k4Y$Hj0fM&ID0q^XzEjK}huv$&uQ(6x@BM}7zKGX9J zU?(_WxdIM(8{i1qA0j(-R=-}OcSATt-End=`EGvKEb`4n;M04Alq+e->;$a6N9U7y zA3ogQ5L2iwl;u^So=ajb;8D&fRQj4e^Bo(+SiTEUwCT2p=E(Q*yE3%{&7scbKME`h z;gJ{O+@XL0eF->Oh5Mz0m~?tq9s|HZtiygm8Iaf9)e=@$dwA%0asV);+ZA4Kg)e4D zp<1f`Z%-^ouE>;CeE$0ddZXljVEUadA!K_aidxyp>naxU=T~`ju?74}YuGRBkJCtt zk45_x&wQj2!Y|lc=y7`vV7R7{a-^DG$;ISoB37|A>-_M06b+{c@18P$)Pnais5e_{{w9*9C zp&5sfwZ2Li7^dk|Z8hp*Ub3vd7Eq9htcrpu`pCCjSj*@Eo6SN1j*geCy@ZusN<|P) zMYeTs%>8|klF`YZwLYf?heQOWlj_{BZtbX6m)2aTkVo=#*qfN+@M7vf zHtgTC+1o<0gO$Q6>iKW1>3>qISik>Iq8nhgCnctHC;kH5 zKoK@T?ZD`)EKYF1RbmGO=D29DwV+UGPgD$XS@#q>^kl=LhAcC_UKuBrRHQGYO_><{ zUx>TO!qplx1V8qvn=h?GMa@&Nok3v^BC213d8okZBDzr=)W2Z*X>Kd#=A2_pGSFJP zqPQF4#F?iu7`q9+adM>HRE;D5{ z3wMH6MAl)}R>ZpUeX~4Drtq03`2|Dy1gliQ6BGOq1w``zZEbn4YknP#t$f@~xz>Y* zy&q{vOo6NLU^;8KRJ^ms;*7Jdvr-uLWeNNw=01|bZ;OWSRjcnJ7I|*Yat<2YBH#AU zcKcCa#;wp)Q_Qp$tLlmw>}ad~bXCK=40$4CBfR!kqgXi#)IOD94!@n@MvzslCJ0q| z`tY+)7~&q32l(Ot{vN|4pmr9W%a4EhZv}JOno)!5w!NX4JZw!fY(l zsbvYF)n5|nBKRV-r`q+5P@QB%A#SG}&?(ZabQ-$d*~;qOcI$iwHEa1k@I}Nk4vZI5 z5pr<3yW^0J?0_|GRpWP6O^qiARTqWo7LShZ7Cc7GVjhWVivD95xcsx4FZzzOR$Dm} z$&qYogaE~v;zLL&%^{rcQ!}i7aLMuCx!vIxL(Fs!WB}Vw(U9@&GXY~60Zd6CR3U8> z1IVBTVHx$L$~17GZHG}fbZzdV!D;7Lw0yIv2cZX6{*{)mhC_nky zKZd_hvcb}`Il)@3DEQX;IqwD@+WFN$Yd=)ehbTQX-o6D~DQtW`NcKigZ)tw$6bSHs z0mhiDZp^;fy{Ub z_Q1gS?~tFWPu+e08Q>+DPP2A?v2~r0P8)XSxfh{YdytSPb{ip$$va-hWp#xtzYn*8 zh;S0QUjr2kWF+j*5Dhl;>%O@nuu(@vt_a++^$aF{Xr!Ax{t_s{P0^5=e_!9S1w$MI zLoR~wCsu&gq-~fkRW*TyR!Z+RoZsr5Ol&AflR!0QBPHUP;X5roXu6bZK*ISa5wms@ zLq7W+;7W{>6GOMv-N-p@!tTq+-3=&4ONQU^$As-=A}V8pHp>cus$he7xHcD$G8d`( zY}bKHEA&{9$-}nAb)9jK3dObkuVe%ds2i$UO7W1WN$&}xaDRL8-k$)URM#h{&Yk&Q zfqZr966w^`Cf@-_dN&$tmqPbiASVEjJiwe}2(fs@gG?Cb4@M+<0J7RS1AO|2Bi^U% zH}lUZ4*%H@GpnwLI)AB-I=wfR$S^;`)v${C317K(HX8F_R*O~~v21v~?>YFRD{Qx0 zmGiIJJjA3uDdDJ{}=6Kg}Th4iTe}>#e8>DE9D|!j! zjm1)|K&v4XY{ZEVgp;7zI`$(8!ZRC0)kG45d=Q4giRzppM39m`FiV{_9iaTPmWFsW zOWeE{xJ>{xhT;jiZYje)OboEZ9}+d6ejM6ZQNT?2;%jcyD?r+EB+w|!h%};BI%)f4 z+ykA{u+8k@M&A2+o0m`PZfhEuY#>(2W$zimD{>RmOg?oB4s%57(}-~=P*7vd!cX^I z9t>AOpMDuCr40HnmZWJ#Rk(;E>DP{Fxsl9+LY=|dtZuf~#vr8w>i(L2`KCb~MY=*4 z=fB1<^+AO^Qip9*`oP9tMwX@Gqq_>VuJEV3h0CWXJ$w+0RJqHR_M>Y_v8@-v10K*ZH{RPAV_@>TeaUSEW!HnEKB7kV{s#O$aI)j=3=ID~PRpoq%2JAyjrQoV9U z#)d$FKVil|xg8n;Vl0#Ups;UV>1oRs6zc}@nH^B3_x~lBelyjC(L>mTUS8B1B?6 zTVLEaLH;8TE^FPEyoIlm*E01e9X+`Azr2>;lOX#GRsc506Oy}; zXw8e0R^!A~DHFve@)Y`^SR4|txzoi2(dnkjuvXBJJ!%<|pa9z)2{?Dhg(2!J1O0qW zftoqU2+rSC<4YNnt-LWy$M*(WLF*)xaX^}!bVxQ_q*EvvcKp&xGDSDJcp7KF(n5FISL`PCDQIg8v3fO;vC#_6&>RFs3@$e6vqLrM_Z3l-&hYsAzP3#iJho|XJYo@!fv z5ENC6(&1O2tmtgN<};+rO#;{UBhBUj%Zw|xr0H7;82@&?a2FSU;i}tqG@VH3w*>3v zU|*E7g~NRckcD#!!?BME;7}zX`zQ~Z?`8GmMV86K-y*5q&d+o7cZ|t9y^Y3lKOls! z8m#9U;kLYSf&uj7lA!e(r?<+yqxpbT+a=^4+LpHN*=#iB6E*=VUn$M^x= z&LWVI+PCyvtKsxT<_dR2=sjjTMIJiFJNd5dYlf|b%SBTHEK^#k;`=CfW1H8U~i`^chXX^KOT7Db%fO zNuH{ch~0dc<&>^9u0GiNaG(bQj!i*1Zq?s9kHq5H zEXj+fiq1YBhuVy8tk3pWzVg+R?kf)xSfM(*Hr?)%h`Ohmi5(Qp{hau#nQ{mhcqK`* zAXLj3XJU1pTJ)RtqSUnljon?~#VHY>h0>;f2h3GuGDX`2&X;=u4w>4bH|yUH?1*BB z&KT086Fjn8F$3K6(YOifvH;zUm#vf#1`hjwcFHu!Vl&(ng#LT&F9CiLn8o643i8jy zwqPnVV;ja108c|+Rxv#bs`u#S6vk#v3yG|*0iouO&O-8ve?RU6zw$k_{Gl6%TF@*^ zpCBoczCc;LgU=c?{PlhP&?8Pb+^eGakB4|d@=_l{>qn-(UCO7Ae9qIsyNjgo74U;| z{KzO8+%3jqmfxCpQ ze)&6lSY&!Oiaa$CYX@duyY5L4lghwEPEt2@xXF(r__32*0oc0IZnszgfc$Ya4Z};M zf^@tlO<(bAQu*eoa7px9k@|87ovJWqKIq9U7Mq<|h_|o^=_cy>h}tprxldU0UFDc7 zWLU?$&XmYes3Np=v*TD272)9ewfXTH9<4LvI+!@$aqq$Utz0c|bS(i`+RhdrmmZVw z0r~NoErsZ^%?OH@;Hv*F0rW#Isc5z@(3LxoyT%i|BYS9EQ5edv`&M#9BK7cr&6GFYH;lO=bYA05OYQpLKE5 zwYTYV>wP%WZ+l>1_5^l4F4HT>fFjJNE!olxoi)>4P=V;G zN?-=$!y}-p+{El7UHE_YcVg*1sA0fC+GKcES9IlUH6~I?h@j%ojjP(Mco-mXN7Y(Z zgqFJrZ4M~GyzKLeq`w7k>8&gYP6myJEJ48-R!_Xd*viCd&q)t^p~Yf9H_^@W#D3!B z#OfL-&j@o_?I~~ApUowv|76< zm7xBv!ab4EkX@cOW$~YUSvu4d3b0NqM%pGBiS>qzw5JD-m;kV3v<2Rx$&j)GB8*<4 z43*3JR8XvFth0SR2ZwUo5z6|sy?oUU#a#YZ3;jJvk_nXTBU~yGQ zE5j1HYPV{zY($jR{#HS-jXKo}=3W4C-W)MUROSggK^SmOA_&jP6GN7oG8;A5xq309 z#H-Z1fDQ;!0-7HJfw7EQ1k;^0uip;FbHAz&-z$iA`x&dhTpy+Xr7as}i7o7{*!WQ^ ztDyyJ*drGb+k1gfki=VAc)qB+sRoTlBBh2RmMd-)>5UD#Y->!JT& zq4<0XbpU8PB`|hBUjLvw+I`)9Bz70zlcO~~?M60-T1a7aA96W%EVx!>K;(QB6dcC! zrTWXlI{H_mBrD!J*Bi|+g8@8b3te9-8LdSfa@DTaj~Z32dT_lNa@Op!hy83%Y7z$X z>0&-&YO5Nw>_YpT%wt&r#+|F70ht$*Gw_eiJYz6dChoydS?lK%v~1s__y6+Od;yeY zc8}WVcZ6k`>q=uc9J1l0q9}um)i(g<*x~WwkXS{89x)69&g@o@MW89jVIC*x7vRA= zaP|P*u%TjC$82XmSAhVQKfnw%Iip+kqXb^aeF8K6>N!lioEZWy%r5}| zl+~qo-(g{q1lgh{MrdEaZH*v6X7lwxZY@7xuya3~-T-}z$R{X_@m;Jd#9Jw00`Jsq z;|<3K>~4^+)?FP-ZHSrS_~EEU%2Bt9&z|C?WlXh=sa8m1ey&TrWhn9LR=MdCEKpij zxchcsXq&;Rq7$Oj!>*3gH6CU4#$Sn7ydb)ki8f1kL3D8|)YG^}#@Q~|pnSjC1gVa#jgK@y_p z7uZ@~!%dAy7mAE&J0@ACY#!EftK2g%Z-j%(zlRmQ(Z~5HfC- zAnJ_4PoE~A;#oP3;oWRU^=82-G-SQWy=qb($jy=ULdo?jeqi)XpPvWEfR2ig3?fSS z9zMMrFlSo+Eu1Y?S3Ki6ALk1o@VO#|Q0-Jl({E+}WpbgQaXy!0O1%G|pVY(Q)SFQW zTI(MNf6ohC{i9`}t&}t2=vlx%1mVWai1FmxzXwxbNR-dvFA70i1lyZr2ZE5XZ!OSy zKII=bA75&W9Kk|fgVf4X%F&_{aYRY`d#XmERe&xda(>cZ6rjv`<~^L`LjuL@$0EOU zxX!SgaPW1uOAO2m=jEUnz&52B;W{Mzl_$_d$Zlkt92<7o*r8`HCBH^sDWX^PEY>Wh%xl*)XiOhwsSsj8j z&QRkwod7Le5rRmt9=7kfU*`pHBI!LF{J()1ojb7Fsstnqnq>*9-k3am{#lfG!5?Tj z2m^e}X@(}w4Mm-9p2Qq)*i#scJtqL_!T>Qr;+0{xVJ`7{K4+iqvj)ksk^Dl05mq~;v$7XKQ+FzR1bdfmX3TwMiQmd zcLlU~Z>y_Cmm%J-HK_3M)xB(ZzLqMxtq!!b)xczYXG?tJYxs-Yv_)=!ybB^_`k=xW z)52=26VqO^j*j)}I!cWP4-lu6nfz_BjB&flXuW9(am9r5i5nC1AO6n#HbFz-L(Fp2 z^;gNcblgv-xTVHtrBYLmo}8lh7FMcs-i6r;Z}CNm&Tx*Z3i zB#r6Cw3+enFg3kL5`!l-REQEp8i{NO-1n+PM7KrbEx6}r5dQ;E1=?U(NDy^j@35{} zE=3a8PIJZv>>`T|Qjk8)66H~@^0Rf1Z{CcJ?aRR1wtK0cPnEmbT^QRrT=t7M1dkN< zCR7xHPrDZ|+e;5-*^9eFTeg1a1SS;Qh=E>IYeBv(?`@XNb@xYUwjhXQK|z?C<{&vG zVghP6b8lvu0DN-J#}{YEUEQ9iy_NZo=mi z*3RB;x{&5wDk_Ugem7Jq8BWCk)~LTd;mCqIfHiPoKYbO;#xB+LX&DcYj^|7G>UX`o zz<_sTwGYA*^kNQyjuR!heviU_SJ*+D`heXs`pJQ-1XB}d{^w)(O8mYQqvs#%^MLe3 z8VUOd2*u8n>=VIoseRD4nflL4;P3#3m(6#j#?xa03G6XKMV_s|U%JTO@DS+O9O5pJ zL7(J1oEL=goJ`B`pIh9C=%k4j0%T5p3#Ih~>nWg`oBIy-`E?&a=8>=v2IX&z&jo2> z*9fIgbtR5~SGj`0OGa^6r4aOQwLzm6l>)Q4jH>d7r-E*D{Z-xWYb<% zj_8^`ua=+5sq>;ISXlPQ9OV(i~zdFW|d#gT{dDaIw}>KzomX1tpA~5N%hQ-0CQc1I4XU zxtt4!3?TnI0?UpFK~X?%A5q?*-pGir;bu7ue~AhvIW7XCY#-fk5%NGr0L%i9!Owl)kYa?^QDm4C(AlImlECH52=^l?x|ik9 zc~9S1E7pggfSUOfJe?)4%f40xNmmNRHDby}ADNCtB{agkh%*+zMW#OC0x>&5tkk94 z!v^#FSZNj`!U2O<_6GQ(N_`n>wD2C3x&o-Wyi7fotVETcZ4>U znTBpMpw(ie;}jk9K!9_&YC=gM5;)zH=$Mn{wk4N~TRFSQjq^)Rjm8UkM z`4oBDkFBnP4l=&vbYV0&1}5-yJ8(0}!v*~BZTH5eeIKjRp`7RYXZscK%-puhM#*QpWq!eHI}_9tug8oD?BQS&it1y?+U zMx9t@xVbi;Z?S82OSN7#(koh3ZJf!u02HWqpx-LPY2`LV@|GXD30L0{LOnZ~rl4mL z^kNnWDT^Ky*}vw-z7M6?h*cRI)3a+t5uvH)dT1P+K9?>xu2Rb!HG&QP>v3!4?AXlD zhaa>JS)?I{W4SHl(B=)ag83wziDBDiU;g0oH@OJ6IT0|x4TTgQB)%m^f{59IJIxUBz3C6M9Dr1=ATuM z(FWKZEnmRFc}$9fJbJc##Jyya2$0?c?$SB?pzdUF-jT}-6w0>bFvKiaooXgB3)ekbz;Fci%04teB$FhcoGTEH-&wBJN(-8nY$Z# zF;KfQ)%we4qQiMo>?g853dDr}evvB)WMJ;NNhQD2Re6P70&wfr@thK>UCI%ddfr(= zsP>+oxOeiUN_v9ALmv&U6*D8xX7r(!>0ayK;nL3z!nlW`0vCHP|R$hy~B|c%eW6^k_9|D zHU*%o=*81Qr)wMT)eGzX;a^LmWtg`@`8)O6bwg^d0_tz~a)1W9B{c11tN|yp5!*B@ z8>~ufhB3Iz;Dst+@@ooC4*6_b14)DUXz`_yN(z>BgMTm}2+mhXkHD#Aa{sEBxZ?OP zuNWQeHvXvYzXeH1i26qN24CaZ$J1^$^+Qd*s!jz3he}dg!|*m=6ZC6R3}v#!U)3$e zslzZ`8oG5|2Se)6*|d1Twz%;JXB-0pIF$3L!`u%Zw31CwN&&cpK8TV@w9>BoW0Q)R zsMY)FVCvel`3p>h<9Url6mF6WLqH+fh+dg z#R_ze34L^YlnkY%y?Bo2NW8Wo3`G3Fk%oSFvDeCr)B_0|Z1y=tFK7^PD)0(3Y*m2~ z^);2*4J2dveUql7Ag?-z5kTS23+DP+< zz{5My-afaXO3+jIH)sAAe}%M@WTyd89DQc_+@V!f8n4#Gh+Fxp z5)hx7BBfdxyK!Z)aXAf#zZ+xhy|0$yCy!GkJa=j_R38*q{)1aG(0uI?9fz22t96KVs9_O9I2v8Bz zAtlUHVjD_d+umKghWC%W38kinWdJ9-^lW~Bp6JY?{_;tgZLN9{nZUvMC?Y8U1Wf$= zd6V8qNql+B-l}(nu-p&1q1@X)Z-#Rp34}C^AyFB56J(ITExxnyJvOe3gmn+!JAMVG z31ehi>iHmV=l7EoVo7Y{G*(W~?+R|Aj>n5UO3l8*)igTekIK75%!MKo5=c&h(t|h_ zja+XH~1&d1r2Z}ukP%j$<-2nh7wb-q~LfkE0- zlI@;&H`wiiH3)WQtPm~I7rVZG^#K~{6&Rq~;Bv1eYYfX;MhCm+^CRA>K5a-a6^wdm zx{ccRVVe(3OqV|D2qKnuRzyHmwtMQKc^<@nc<`n2PC4CGpfkQTecw9WP))5$yX%Rm053sB9jZi`v)QM{{exxhZ4LK7l_;OH`aIMBBcdAdEjxgi7{BFT*q)CJ6C%k0 zXFZR*X)82wd6qF9V-81tnFUUHmB7XgEMw-QDb15@OMIVi3u8YtLoNJ1!`T-UsLQDP znVM~P3haQ?ojDIGoyL^ZCvF%5wBK%dH(e{S_hCp6f)^Z6*qcx=V0p`1$acEV_cn;7LazJCPZ9Tzd9!L_H2U{R#p6YcB8Wou$jqlu23XW~PjyY)@{aXy7l z{q|97BrglRuHfhn{R$bj#3=QUqksg^{QV+a9s=`iLS3qsW8!5wuwbD*9K1jlqpW1q zZU@M_tToM)t%e)HA_Odk*9xir|P89&LqVa-Q7;<6uEkp9Yo~$wNTAg9}Sa|ZD_uQ^fxC4?YaXENKWG~2e z13X=^XM0Ws8BY44a_X05q|sybiPM%rLw~y=@fgM6y$;7=eRx==a<0C-lS{f(E7!Z8 zF7yi(J!?77al*Ka&tLLZuUlLZ_QmVAlgzqOBVdYCb2EaFW4(OYcT35z&@n3fio>5$ z?n8(sgbitg<wPD?A9u%w~7nhr8!@+x#iVr z+_{x*V2(Q;W;b`a>8Cgr8{edYBNI8i*kD1F&(?e37Zc8p4MSaCbE~>m;!zfg)~jM* zPWIVa>WFv7z>PHN*uzIF!njd*66MAP1Sf~{NBOfvaJWr<9$WfNtj3s^vK1liS6|y!*9&U4cx= zFUFO4u{u}wZqf|)v{1H=4rhzp8I6YY!)Wi+g}OBu@w@zNY)vU)d9YM|;3@dN&e(s$ zhr_Au-4TxGPnnm9CAJN&<6ufDMoCJ z7$7M(86ttu6jj&I*kElQ*S!B`l2|yyQY9u)uMHf3?AjX%lnS|LcUP zv38e{z;U%}t^vRoSr2jCO9I`}Cd9QidhoK;vrhC30Kx;N4&j7?8%S+?E;md|;&QEqa^SQD6bhj32QNunlK zjkxz}TEpLm(|3nTi}0k`{F6y?0p12>kwqOV`V=+7)6!z8a4pU5+U4xm%$?k+mNK|4 z6~ol|WDvXWZ=EmPq`~_n8hy(`C#iOyXE8#K(b-xe=d)w+)Mm!>BMA0wH0-4C+Kl;} zT4qLSF{WP-%QkQ8;3?YaE%pRcwKqKlG+jM844?N@J|*B)an9>AuCmv^;E#V-$Y=0= zvc-BqsWJ@gc>$p zD0F03vU^$@iF5CGX{)CLE-(uc5LbgQimC2`KxEr6gbqKuRxS;N?y|l$3?bVJzDj6Q zW)W7=e2rO%)-l|R>Q8!%59=ORpxiJIKtzcXa8tf~sp?Osv2ht~YVq6R5~txdnp(aa zbEP5j!8v4BG|J6`gYueEd6o3fBUIh0YGs+zqNVq?()zf3U1WxV4vc@&NK99E&CUN9 zPRUNv#$$rC`xu=u2a|zG#1!gv@-Fp?tzUXQ#IGHYm&Ovs-L09*_+P{o7NN&aM%e+n-5D_l`5(BfHM1Hh}k(KgaTE<*Y%ns285n7HViOekH3F#T=M1i@)LZHQbZa)@L5ecnqKM@zPQFjI)A1UZ zqo{XcZRk7W@0Vo}!oV_ONa%4CuC#uE4lqGo!Z%9nJB4kd9-FaF=b>3IV1G z^?$41Mo{Ug4V$W86F38Pr)}9JDH<7kb>Gh^IP^cf3+Ogl!Z1Yx)+fxxnb>8GJ@NTv z>+&Q`J}r(`7dJp%ZO7Bg%j%5^7=awj_|#(W;JP+M-obuE0k6Plh0$6PR~I^+cbA2*rKvuX^u zlLDI*-_9mP8L_R7Qv?!2#*Aofm(b_iX~_^5%PidcA5;TAk9vdaO4-6>*oC3fwD?$~ zI6|8B0#QX2?}d{fQjyM<>50SrzYD#}LCppR(@Z}+wypWZ6rSsg@E@nT@@>M5O1-as z^{4P+VS~q0g9ki7K>chRq73;Ge;-&ruIB!~Bou;#w$=~Z9(C{X**{yQ>qkaBiV)d# z*D;FblzeFi#H=i2!+yy<4j{;jHt3wuK>xEu&DjA7Ur6hfTnNkat6LjNeEqNFod*GN z&(s0;K4@(Fwzgmcp%p~m`vl=(%s&XF4N(M1y>TW)R=bF3%geG<6Ph}ePltkw4sn~C z-GTEbNxU~e;*+SNqfN9(d~lIcUq5-@53QZ6P`yDZX*k7T{2;#lu+9tXeXhiT8Yd54 z<;7z<$o+435X-Irig10N?S(q&D#m<1r3V3%wCXhviW3?6V36%f0Gh_qnFVs{XMAGz z#cbT{sqNpr6S{vk;nk4220k5zf&d4)wlu>H5RJxlO4`)hBpl z}Kw)257=off-;goFw@vT$@2jIhD64j!B-C7#-g&%&She!ac-@t&-Wt%d=FC!V zVl?F^L}1lxqMxtZvAWe83s$>i_x%bK5)*U=X&rThEuU`ffV{uEG%e)|gXF=^uN4w= z%r1RZ5c_mdrd7ZafF~D;9AWG}HRseL20sQkNo5k$4VQXT9^Ublm&TCtCt-@xekQO= zS#}xN!O%vHte2j5B7WSnO?&zrB6w74#LJLA)jDR2H7*Qh;H*+st1eifgGgeGj{WV` z+>LnAZkYPkvI3U>l8@rd29PXx5MZ67P3<(~9z;1%n46@}#uA)g{)M{(@N?nXP>RBc zlP%I`zj!NqQ+vpT&*327eh&ol>5B8j9VxKqCv19kw%K@{+gIL5o=UO*qMASueK+>E z_+JsqawpZ-fR8Pel7;VP0REKs;CSPE9Csgnlg5dfH68-&fNfFYosd7TK1%zhM#rg3sdOpIZ3&+`t z#TtJfr~-j4-2O_KR&>wGJ|9#*qH%y-L(PkayE}Rf#&--|~Dd=@Z9P(E$iwUiCf3xyF zEl6{dJp?_lHyQ@+uwAcwH$y&WEd7#Jh8V!t?vEzaJEt>ggY+@0Q5d!^%liVF0xIfs zVG;eV3fE07ckWU{wnSAp&n4B-_12=I{I#8}&fzD}BOznf`E&X;BbEy0=k?J1G$Yn> zel-^%O7?6_o{`XZjx`9pH+Z&gTZ_w}hM=#__1w?LikO8Ncn|~hnQtK0_qTSdA%69VRIlC<7AMP3dl`) zJO8kGKdPEjNJ%7F_wnakfROl0qmYxhJ-+Dc(>G26A^D$o6^8uYchn>5fG>- z=#^yBq&=Y1)xr%bTRmf7s^?2(tfX=Aqx5Ys4d*B_DLE_t66NmrTYTBN>A#HwSEX9V z^;Ci>b_>M@HWb^lE&2PFggJFw$PB*deGM(Ubu5NHZnK|{fQ!n8B8MBIdGGa926?6N zX09878gB^-<=y`_9V_7^){EZ)AFWq_oBq&51s9^C_KUAHLUeQ-bGBiLQ}izChi0ir z-UVIKcrBzoSJg8dols?LgwMVRmYUPXPks;*Pd)Ul<}uPDu`Cf7)Y>$ zAKx-!6{By5%R)xB%W4l!+=U3b$C%UQ>7_ClH61zc$Z8=dLW6s*?c8=k!my94<1G{m zw#8}9wVvOs66s(PeBgMMB{N=1O##^uUiAs)bP?L*hR&;1H%SS^;*#~$Xu$x2cgNwG zKP7u)Su{~@ z3ys0T3<%EGg-fDsRF3mhmnJ~_-eSSAm_e+}&0nGNX!uQ#7WT7Mf_pk+Vt?f0>Z&(Q zi{8&MJGbDIyYR^*Kr|8%m;2)~hWW!{pQV|lfbHej6BbSHFOZiOr89dc4HRA$>QAPKgv8L(TId)C^ z>evRHI5jC+lADomFgYGO<9AYPZ(_!rYC2vrl<}zg7I3=C7hK z=`v;ro%E#kQ!woV*Z1bF0_nkA6?p*9Gs>_j-YNFhw@D+$;4cBWGY~`BwyR$m;$BAD zLt%l>{NMMl@N}G8=f4Zt-d~-=OTdT~Uib$5Dct8u+~M}~{hPzyIW>ZPUOazSk1i3s zHN+CTR<)HAT>heO{3Vo(bh)AjK*^}6tl#67s$;w{ZTIX!QEfA_mR>v3mASHuBlXJn zm#%nNVf&*wYWn3#Q!JXTQeQKk@;FzqQR!4X#F7_ED`AxZyK%o_iq?6q#JwuEWMlj! zi7?6=-QII+dVF%S9@4O83j~&Ja`fr1cUB{brPn#}9`03MnI-Bs84K1u1kZpmnOYf{ z>Zk+7g;h*RL|)3^!{*P&N>o=``OsJNGr-b!{)mFnW%d_4nJ@i;L zpq))L7X`@ZcleP-aSSSa3btBikZfjK^)vQkQ7vRoDvaRVUN}@|6tAK&Imv+P;EL5= zscNf8m^lPK4K%BV2m&^yg;;H-jX=KE@(&fvw;1a;a#~pOcY&?Whx&+L z65U2IY5cefKO3aQI%K`0gQ8mlpXp!JY9(frHg14Emn!DUZ+O zs+7z6D;*6B;JT+yR=2i6g9Zp(l9ezaxpw&XMk~-p(!Kml@$Kxw2O@h_Rl+hN6%)Db zV+^lwA3eR{Zop)gq&+QhdQsOrnd5P~KcU?iHq^DMl64TI>K2C6d3{A2dY7&ul6ta= z`pogJz*E{>|664N^u9_<2z+k2l4~_VlU;7Fi`6YNSr@z*NkSGx$l{NqK56rHq7iSZY0# zz}wsP*(St~ddh0OqYNU?IQErNXF&=cY4bAo(Vr%HI%PpoS)Burw2-&z34`5dqE;Ne z6pyi@hhrWtl)O3?W_q(AITovI#{>049-H$1KtrGqB7-ZuVy(8GyNeYs|5@Fs_qOl| z$;MODiD)f&S}l%Jer(hL*Z;{||*uXrUlj3o9N)JZC8 zAcozHMeH^BlxthrfF_a7rZ+aq#~Jh<#K{q^qF707xj1=326AE5vlGBEs8sj9q~;G< ze%Qtx9lp6h3*)nv2(_Vlxl_MR?f8HB|M7`5w8=WDC^<4r#ob1P3S)nYTN!DE>V<9x zxuDR`RYB=T#cA^yowa2cX4-}DANW^8O2mGGP%U397ARFcxZ>ce=l_aW^|*NM^I#0q zgKauguU@?-CuXZd!GXAByv zjJoO+x>E-zt`PZ{$h8{aK%v)H$?XczJ$}efMR<1IRQy8SrL$bhIT4FiTY)q`a%RQ=Wj61xDav%Q?ElzZYS_%&! zh`xf4XY2Kor)vOxK|abAHL0*qD&Jf@+Gz1v1|y=~3Ea;a5Brl71uOQ>{fzYAINTA*#sf;f42CeeGZ8Tmur`_j7t=X5(ikS~d6 z9V8z}6V$ydL%V#w3}9~h;Q40Xu}62gyqE@_At6;jm2i?6{jN5*OESK2X)b0mU5jYh zm#B0YmdMkHLweM&uA48iXJ}$|qJl|flzVxY^yJ&Sw21c1zmp$MQTlWn`J{a%k4Fk~ zYQk1wFDwZTlZ;V&2%btSS5g&%)Xe)IMR_csuT1*iFF*Cv1R^bry_rfnQ^4?+|LA=Bxmy>`+&OU)*k0veEy?GMd%?WgEaNXPHZ#yMrT!WZb2 zMpdTF?}kd_Y#F2Zobva@$%vm4aU}NWQJHrsOPS2NwJr7=f3wds!}mIdFi}lT2*q`h zJ67#fA~H%b{@5Kq;sZHcfq}()dihF;4{-vlkj{9TgC# zZpK_A@a$aH<@WWq)APS2E31)a?HGchR=%d0ZTX4>`Yf=C_*T5+A0&IAejAdF4C*P& zj=Q1!$c-fUboQ@uBTDKZD>Voz|6Qv#$rkGUYb51nBaT+}-qU@W))xHO`uMlLGTvVl zo+Q)+z^BU^-muITqUx((CjJJ!!bTz-r;{A;p?1g-EN}5FrOBox48oKhinH#8u4Z=^Zxo!KQly;{+pL1u##wdWvz^UW(lBm#*u$%^5II`w(q zFu7Pu=+BQ3hFn-tfBpL^bo3O9#pK?75R5zjkN+XmIE7(pAOsF z1K7&_p3qMHnQ^K6RY#-`b+^yy32QsT%XFnqPGYjEl@G?V3tUp}7s^VeVlW!nd zrk)QczwWy*7qJS_hBKKrAZuq%bVaFpdi&o?=8&<*7-|m=vDAd;*q7fEO)eDDSn&UY zxnFO++Ks01U^M7hZHj>rSnPB?bE$Jbw+_uf#frT9(KjqUrSV97Znt%mL za15HC+pO8dW

+`=f(l*zxdx9;I3zWS89+m92*|4O^R|okjg=u^Nx3&jHCV*x0_k zpQUNqn46G+ND3uF1VHs5LP3R zzBGYdt!EC-A6|RA9%#AGu#XB$6;JQ2`V=Z&oj$M@pPvdcHer&8(6WUlLq z5&V;sx7Fmr=5Ot-Xw2tX|FDx$?YYf!zqwv6Alv(d$!v9yB0`Nrhr0hHWZ^S}v=z@X zwG_d^z-8YuSu8M-(#Iq$n)OE>>ntcXWE@TZxj5|JmD5(B2)V@g9u_{z?0Qv?#QAX` zX}p~{6(s)4zdlwiB^YVCH)(hr;&$f9Ge!MQ`lENMag8WVW6J5DFi8y^w&P)aw4MHj zcis<>XR-wdr|LFJmi%M$oe4&2{AxzCARUbpipuZYaB+>hz}Q`FvjYRNKVsx!1w{Dx zaQJ(l_?T4`Z$~-(YZ=XK8);j7kmm9>SmR<=sbTkt9_?ndAF4&ty>+nO?U=ri3|Ak7 z8gmqADXW>>yuBt!KA-R(Ll2knJ)4y*m3K|>FgoETijtmgfEf(<4wGH6NQ>Gyf>V{6g4m}(WNza9L z8TYvYFUZvqBOl8#W6VH){JlN9S5f`MV_jJ6i4f%i^Yc8e>WM~y5C1N|Q3Xdccaj^i)CSvlOe@#zZ13M=w{k5wLXT zIuu;P0X8ADoZFwtnc<2lAj;R@0}2d+7+|9Nt`CCMC>5g#kc}6x7hdy*Yt0U*6+xIy zmoohh`j%hR|Boont@93|7D-!XAT6g$z3QZZRe)<)N=aUkplPt1GL`@@ARy1o*u+?M z&|3JiPxK{e&>$z_UDM}s{tyMmN@#YL#{n|-!^(I&Ew2I9dPcYkXf()=1d zaJX=)NeWU*{JcfOXMNQ3N|j5;`sX2!_6v4oG%=Yir8W?K?&XYO(Oj9x1mTN+L*#+W zmD#urwCaKLuSPFyMdZH&iBjVHOu9$j8v% z#s%ciK9d|2$Tr6VAX~tOTSj(icm6r7D#e^_E=Q^YQ6)Z2Hk44^oi(qp0@DW7cGX|p zd9v|ETT>j#Z@4V?xu!g~p7wo#GZwz=gj^(&qO$*_U~DW3Dk>?>RU0E>J<=<$iDXlF zoDWeNFmN2qOM!3hjVDd;nw)dwA>n~4oNlzfRjC(-p6ta|)tD-fUt*8tGBIJ~sYPkn zIFtrZT$Fs33eUv^X+$8B+Z0|rM51H~h^22okTfm<(hFWrD@$Sq;Kvq&o`4lHi-u|66fyvi?G_ zP7@InrMmZ*uoKg=^HN(QGfuO`ss(WrQ zqjNai7@H&L{lRX+4Qk6q+dgCU;A|Uz5Xdg60I$yr4ZfZJ7o}q#aXKfv#jL&Vol%&=(G-3n_fJM0xVk(I%Dj z@U*m55KV6&s@2hGw^4)>SW|K%3k?eZ1~DX1JnXpQbB=8ZYz_uU1CLG5h5O@8q>le% z#Y%G(`8fGe4)A+&ETVB|Sv+tII3XPfR9Fg**l!bRtJ9IBIXdnCdwbZ#&o?I?0iG~B zK2Fhj(Tk|O)T9yUtCLWNFZ6O$;d3#PTlfhET?;hYyo76lJjJQB0Gn(=1`%i%GFYzk zE;*8bR;gh1`lmC4ukA=9ozmp^okwoiQOINj^RKCAM(qr{Nj>Jrtv%#|m}lBgpKaiG z^$)e0nno?ul4x~!Hg_i89aQoTTd#CY19>cO22l_G+hn3f!`!_bfe@<}?ACr#&`O?u zh4fx=8%iFqV@JP<3v4sDk(wgD$9k(AADBN`Osi8%%8lkoAHDJ}c0U)lPAGz2&l?p~tjFQg`a3R7I<;#X{(p!PJ_tv?r{>|FbF0Gz)d+__%*OU~SA)Ee zv_$V1kiAuw7e~-FQtR&aZb~TC)8sC0czmK(u4;M%z7O!x= zfjra`?keSRnZpi^E{N(Cic7M9Zv$W%;8{x9sE+ zm2xgeZ4Vo3!XuxH6gEN#Ep;XdWZ|%j8wXj9Q#>1wIro_Y({I|DXS%xuE;lnhe<$$1 z5P0>U$i+>ZE&x?Ps=pdF;+&^uVU0UL-~vi!y-D=rad_Q_65C0gpu|PD8pT-F98P$A zu+78nzY6 zOSl$aUMH$2LQ4=fSkD9d$pFqup5*CVJG3n(_gX~BjRA;2BZ2n)d9^HB_Qo7oyBSH1 z(g8j}e}yAWfX&oB1Weasp{~OmLb(W4R6A%2AE9}^-Om@=B2WcsBOYn(&k=z`Y2Aue zz||~vMZOzMay#UCGEf=P=RDWo@IUBNt^z{r_d;LXKzfO{VTRWs3)0G+vQlOOO6<`7 z((0~|^3`D~xIO&rc=Y42nNmg}THzT6Rr(rA5$sTXp6D_gzwWe$yG`bl=N0^9##j=u z;2RVgQm~Y96~eohS&Rb5<)Fger_peLIH!S_>wLo6r_*@hDr%@l?lO&1Azwp{Kd*@h`wc%HNHw!- z->H(JQ5DiV2=Lwl#4P35ImnxQC;s!_P{55dEEd?@8?<&E`)svCetr?#?4I$|Sh1`lj#2>%t6 zyUk2j^I0Hyq(>tsW60r@y(s1QuuKS6a)a#G88-IWJ&}|RoVOU(7093{&+B^2)~3E9 zox5cTyVd(7xd1=P-x6kioT4{lz|3H5KM&$}k176JUSM8LR|7LS7hAKSk5+#Eh^>wC z)r$`ry#|4-fo!idBeKLQ1V$o!ZvR?vyxM$uPg*pBf>WM0F8N{Eo8k;_5fGf~*q|Ls zyn;dV*)mp9Oey_s&jywY^(<7cJX?b|E&nf1kqSp{LLC5LhNZLH63&4J#+XCvsK)8Z zJiet?NXOEs1vqQqOB*to>3HhTt6@o%D*|z@+^#e{!P>irzZeI!D zgB}AVu}P7&+0~iXlCW;s+-klTaXB8QCy9T)G zPi$IA&gO#Gr&$eI6jd+8b3HZpjRCHU(vT(1C7Wy(ybF+(x3qR=xq9;PiA& z-DB??yMPknQs0`g$#dts#R+OoZ5B8U-=L5n|0#0b1-GO3bZbRD-rL&DJXu9I z*9*LsWUaVw!+i%8S{O>_{l4cwLP4-@EWO`7QLwy z2;MQ4jcpy6yCdMQ_8^g^*M@0DG&c$nH?5mQLe~+PR~F(jVic1f{kb@Y<&+vOHRP)( z1cG#0c80AIi>*ma{;WlA1*dNJprO+FV!BN45Auw`rYJhA+vUYDXNNj@OkVSQK?=d^ z;`FRL1#T)e!Gd0E_iMff5Fo;VrSJRQ6pak$tI?3?U2~d4b2yw8eEB+bO|H4@ia?UX z?bjPxDCjd@furw~$0aX92XiKcO%0t7e+aA6GFH@2^k0qd)3JlmPnpD*HqN&{`CZR(I{?Y;&A0ZrC2Zds7dn#4G+&6clETd^Ht&pHubR+p7zifc zYpY#5;R4s1*+HGb@ua_^e~axj50SGtn7=$bSQmf%TUlAmLQ1)foA(apOw0WoIHR6zH^&FVkiWIO`tZL&(lVI|K zE2^xp&>cbFI&jGG&cL`7Unc>sax|kB`M^}9s^>*}sYxBEbdF1*ngK@(Na09#wAHH>bdO-XI7pHz{|=3viYWa)aE*1xmshJ7FZsY?ql^u8pNyKTtYn@;CZ0LWeP5zb zJXaO%S9>L`;;+`7bTy6h#(K0uTO3xSRns^TD<~F80u&c(wHax+Hu7Dc=;#^*AmLL> zq(o?*inK*bOYZzRq;gsMWi#@{gaW$&Qzp8ZVCQO+^b~K(9U@aHQ`N4rj{$iyS)Skx z%u8tOXGG>l*n)24cUr3_mUqN=L7koe?Q3z_abF3^<&q$(a6u^9zIpQq$FIUg@6AfgMDVuj@ibA!7^FB zg-1YeVW%s(HR|pIR$U+m^WyUv?`q}IWKp%&XK`TlDkgN02Y~^M=+kaoBgwUuh$5$j z9P0yF%HSu+6&?E^xd_!0PSsn<@C;_JGZ`!V);sU47l4N%*vCp9t8nU*;RjazHC@)4 z(5OCl`OSQk=44i1){vzvAeaK=n! zkU^oViwB{>wpWm-GcnD^olYWI#ONR}MvJp4Aw`uz{=nU=ILbT&5^%wqepU5qV{7{q z`}FIzcu!&$hQNl1all4rZ~Gj3*pk-EF6I~13dP_2~2$&_dD{!3Hk|ys8eMs^@Ns?RN58QlE7V9TO&NbRjv#WKj zukqJ$gdvb_oWdA~xB@_t5udV}3-REBeCPjjK9M~pV@B$BsfKr4xe zWP}qLZc;kID%sX9k7})lT0Duk^`;!X_R+2r96L?E5;!c*t}`_6OsOREx@Huu?GYQx z3pCqz_`J8^QPoB9f@?N%^)t$bTpaSI(~FH$a?zjVCW^ol3eA7W_Kw^r@4a^$Iy~xW ze-;SuSNVgAx_4<&3RtS_AM5~|)H}b&ux8rjuW^eO(f>{r>rQ3Bx|4?@kRS%dF^C;-erIFX$u{XEpL^26=T);lomNb_$ zbz~)HK3BhbyH_t|3qsfPG(TKY|2OtgGfo7+n=DH*U7>_Dn|T^3G@x$)q zcQte{ymwz_k=Usd;($xI69|oKsrt-Mh}~9DT4NxX&iVBGxb6KHI-Jl8amAn@n#!Jb z@77>%W2?)q8$$9Kbc%~jR4c0ekBShTB;eFsW+k!LDD$0jvb)ZSC+0eUwm@yTa4Z|3KEr#heMTLN#ylytiZolJcP)5otE$W79TcT_#FHyuz-70*3{9Z zt?C^b*hR56fO96Y8@O6xo5MqvFuJf}Q4c}#07BPAvT%>GuPyOYR8URATY{?{8Yr=4 zu$*s9Syj}yn1FD}fqEy}F@D+=M0X?deV%wCCcj9qYlT_Bx-*$MPVMe;X-W8u8F}mi zJQpnGq=ZR7-^Hw#_6!8N%)>04dWfK5F1~qtww6V5a$jOHp`_2e@AD&S z_wY+3%cqJB4fgaCzQL39Z(JzTN$u0wv)2+5e4^;(tjfeAo7+j4+0WG|@0`!2>EAg( zvps~5aEmm1ta!o(<;I(-3J?<)XC~=!8FGHnu@oNe9OO&{U(jR`>Um%MeN8z$6x76I z}I{-+VzSGR1}A9za-`rozxuDmB~rauN4h;XJgCu{CMb> zatwZ0*4?iC@T!XCfC36ImDT?M8YjDGb&K>vAW=;Bl~>uVkeLuj z{@wgD5w)V9?OR42?eGboMW_^znRy}URx;)|Y+KmbnW_@t-MVA|4!d)l>;-VY5{{gz zQ3_fTTjQ|+K#t7sJmP?jU|<38T3icWZ&fV-An_H-B1BH9xC;1)L`~8`Z`dFF_QxHs zJG>=C0bmF6(_Vwj8`$WMl1V}3Ou;O{+{f7@l}8IK;5T-CW)~()h=4~K;dXmuno(P9kw;>f z@aOI(Fw^qN^y$NC2`gaKp$$+x8ETMtsasQUCD8w`QaqZ^)K&VleG`>R#uVzg&(02b zegR;J3e}F_Ckw=rWP9Mv8gHl@fa)-~pA^JYss(YE9-aM!TLOKI%M~ON-rxg`S7wWJ zX=d=N197cSoVw0?@f*!=rK41e>{`0L|5t6WSe?WTxA{3>-UX*%x}}cNbaXtw#O$jP ztBo{hVh5B+A^==xe_Z7R<>|p1^RxdfCNUFEDc$&3<`lZ!p&H0a-jvkb>x%utnw~xp$5G71VVx(lz3iDBYuN?2-)=pgTBB*6u|$QwO5YI5AubxxtqQplVT-UL#K~9evPZU!9c2~ zK$0Ug$&QGt5FyQ&EQ`VTb5|9Y&cYbv`AEiCM(JScS%RbcgZGi@xqCK}*fsP| zCleQpo2Te9Nr$szD&;TCthH$w%|CWLD%;c(AcAixaDo&V?d>krrzM$_G#=^ho^qWZ zn&{*3qIzXH12ayZz^$CHPlqiZb8i+QhRg$0A%kr?9(8B40avm)iw}yEj5$V|pGuVH z?QB*)hQeb&z`UjR**npfTn)*49Eu6rVAvU7%u zuS{J%aV;X@Bfs!qx)l@;j3+By@IWBRPCo41>mAl)eX<~<7UiV3N8~~K|2n$~$i>JG zbyi@AWYS#oEnNTSg&j!c^5Z3BP8hUXq^v^jV)&=VnN#xjvn8s>a3_Xx^H)$o@Eq?$p*X!yjkN*3s)sr zLr?(NUN@U33F$Q=uIAAu-`s{kG-x7&G@SLZYwD*sx(PrFpCD&OPbKgVycjx*wB z3m)_*VMk0k>bdeRe<)c_jp+Ma^I<`95k@3WoaLrXGoO9_#a>@`vU)BnuBcavanHnX zq|ZV5b=~zx2gh|$Eixs00GfR5ma=qNsgqJV)22q~@q3s3QFE>rmSg`{#M)C9G1qyY zV?gh5${pfUgL&@%fj?#URU`VVJrd^g`t(le+l^mCu*d=K-&Dec;?-Kbe4_~F*bo;$ zNRf9G6k*`lj!UJ=j>$4cN=SM8c_q~4j@<_Q@qCoT zHNmX_990miRFVR!5Q+Bu!BW8FS(_V_d|W@o_4#SugqQs4ht&#WZKX5Y`@KNZ4{jS| zB=#wm*74rb*wpfb4OSfib)0eUOg%?|kG>Tun*DI@?kF9*N05Z5UbtjuGT8>u>QTf& z8=3qj`DT8~>4b{itC5h~*$bL)!o|>w9K;8gax(NTFd{BmJrNGTO;`2GSE42`HGs>} zK}oe+EE_Kix26|G+{QH6Vn{BCroKn#-*~E()z(+A+LSEf8x8E84Pt+1x?4za2eFn5 z^V_@e=~*JBmPty&N`?QLop=0Ly`jNsav}n*s$k$JdpTQS1h{sd5JM6{TpO0~14nse=Q9iChCLChxWC0=7 zkP^#0dP$<|n=wE?9Kd4-o6^6Sji)6;hZgl7d4|@P00H@ZDciS&&jBcG+w=@=e z45}QDF^e#ceJO-^la$7@=*1F|ZuJE;fg8&g1*lb2w~30v*k_tQ7!)K1D_n64Hy|ZH zcLkC&dw7=ve-0@L?Ro|E+vV?Kc6WAo z{B-#M&d}gi>*M3%1Xt+Oz_Wb*zEi>C`znjD_Jf8tkm^zI!<8;dRhucpK+8Fpw6XwZY*hhbydB1r zJ4Q(0-`KH->IDh4j{n43*XIxPY>~AMSZ8GRQ#H4L#x;LMG9Pjt4lyOpN^5v9RBHi2 zuztZ}*6cU3xl^&e{j#RQ?Gx0JEA8BwS0XMd5706{3I(I zE0ZNivwhiKWOm_UNPeAjim6 zm!8Wrc7y~)hWu&SY_C%2rJj11c@e~PULi16o?TotmPE`M1%boN{9=Sl zeR!uxkkDky1w34*b?fjzM*Jy$id4Lqxqr=OsWk;An7}qslWr*ETI6p8vBJ5igjQx; zi&qQKQP=*Htd92ezexQ>{4{eh7%Fqs*!N~ju$asJ`C_aq8aZe)Y$H z7q<^jVHHco>?r(~6q+~5YJ|!0jM(BPnkC}W8~RTX?rG}Y;^bV6c6+hOVw->)Js4v> z&(=K%K>?9a*VY}ifty%kQe949#$*(Ds~^P`s^&Ng75~@Z92#Vn-UKuxdvY}L)F;@~ ziBdxZ_`B8ezaSaYX#m`>TFWk^y}{Mw3u#n(&8!H zcsF6LQY4kAhSVxs7ncYBwG`ZfWq-jNL9qd`4yE~8`<1~cI*Y*nNsi}g6-q7r+v2@K zgBw5w17T*m{+fQri%Q%WKg#>bDM9%|iR@I4!sy&L~9&xjq=bM8@ zf&K#+u#>Fu5z6VfG0t$NIs|c@EHa6-e9P+* zv>;Pt!8DUinBrBE%&AIq(x2}*^RrEbC16N)r?%U}G?95k@NivRH~N4!oiy3Id^8n6 z>f~)01eSmDeb@1DJ;yjhGKxj=TmnZq*r@K?QmbW%Ww!&q>`%IuRzkcLV*26044T_L zpnGpS;uq?-?0iO_r}`;4Nb^V=`VZw)5&zO&B%)*n@x4aSC-A{3yf4HbX{zO!{Hhj{ zFT}`s50P}Z_)yndkG}$1@#T0TTdpPi3yA;UM^`$6?(SX?3yQpEq32-R0<|01TY@)v zk8%JC_cfJxqoSlQy{7i=PEta$@b6#=j4m~1#UO?C_BS}7wt=@|yW32^|4+nEUUg!g zIQYw*wh}z&E^PknyuCtmJ}ZEOXk>#k%N|WtVMh ziz+X{>DN10mW!Gt7`$xls-*J3xeIJzfo-qkQ^PPaFx+gtW(ZvYlx-@4$3AEi9<84e zAt6TF;L}ZNXYCl(8>IjiYx0h}8RLHEruhbNHsEDqmwR6-sJ~s|25ZQn;#}LxKsD=( z(NVe6S?JM?OZ~1*&db954@BuWjuQhx!j)*rC=NrTsqd6Py!8HWZVX8i3TEABh8m%= zv5Mc746x|WaTN(VJdpGV<~$Z+mzorI9;>*j$t57H^nGERrwei{5;%bmy zZ*A}Qk1q`>h&LuQM&4cC?VudIV<@QF>$$8!?pUl(I!#PIpX>F&)YYdwX#Y&EweK0H zN=Hp1#1GjXl1|;xH=OIGC9+u7KK6oG>;vmqngL` zd8I8OU(8s{oV{M1OzSk-hW71f6u(rO2kbDX5c16+_9`s}g@8HfEa~@VHu-qDdLMg* zwTOC_G{RTfO7SwlRQ*_CsT1MPomDJ2`H4zg+Q&=vHj^f#h*mmb4cH(F_@9rbAiH%S z`Z_#~jEH-jKaZCy6CFR;+d3W+s=x)Qq%AX~>YqK592h5ZiCxEiTD$swp#2@Sut$!&pw&<6lp^*l!p|VuR(B-V_g`bOsluRF32u;$; zL&$$>jTm3>k)-Qfaz2eDpHGrxKa_>DW~Gm~m@Z=d>HvZ&N{WN>c-PGE4}dglFj4xG z;+8^j$OT`>)ikYFceVr#wUYcW;Lf3QNEB-p<_@+BroJtN)fs&8Fc)E2YHVL;}JMz;`b>K3mQnjvI!jfv%VlvJ!H!?XWlfVstHcC|zaN^|*bF1&cdH;=bzqF@c8D z44YXn>g`hF9<4c<0-Q!w@q+FQv64_Q|I+RNL^<%7lio6niQCH7p4}?M!gnoB4GjH; zMQc@lA8jB$hgP(ZNi`>R6$gq%eV+<%-Oj&yeC!Rx0CIE?fWdQivRt^wCUz_!GmgTGZe#El>rj1U zS~59O4`jF#x^`*0ZAgDHXGPlGs{js_AtK)+Q4|N0TJRh(cLFytHS(~Xp27fSUneZ7 zd=*D-@5_nK;4t*WjZd?3>+hd*$Q(rN>4&c+{SnFf7mH*;GN){08b|eLIIE{qk_wtf z8UJ|$RU6pOQ(SZc7tw^pSokHv3l1!{R@T_TK3V+DWKLvL6Z=kj2s{j;wiZvxKh~Gm z;`_JEt&xr>flkNA5s2z2FDq-fU|<;{FuFU2;xwnC(sP|U@8`CdKb?n6^`tJLT70K- zQLsYP&x>9b+Bh1E3|Lbm1?{r(YsAC?WT@>mI|ao8UpA(R6N}U7VROL0d-!OE-)p7 zdUO1u0^%p^oU%0jp-d{-L3Ua#I zbB(~`ljDfLFq-An-r*-Zi%Es(`L{&g*VtY!F-tUbAIbI>8-eCv<3?6n&2QT19+ zv3|y_W?l{Ew0b8SOl&TkK(@FE$m4Xhsd>hJ5-0x0+Kb=eLw#{45L;x&Z6?5PB{(Mt zN9%I!0@zfRI18WTZ}LAZsAVj6&*<^e4N9|xO|*WKvf+tW2dsc zxl6(aN1zGnV5j9HP5h!{pGjP!$f5QlaCpH)JM;~R;7)+=w4rB~4g@VwVOQME8i*20hen zcp@GBoJ6t(aBcFYkBIIKgs}U+)40tgD~(X5MLoUr1v?qkFc;g|V{KDQprE)$pstDBvjOK%i+L-M*!PdRJVJu!w+MfHh_#Ti1X%HhDqO z3Hh#3+yI7ryP?>Eb4eV)3^kMbqd?z7D-2z1YvK)WOuGyyKZDBC`N;yT2lNoQXETw< zn<8KDn)PqXF=IIQl+?)5h8G=CH&O%Dxg#XNtwi(^;rS&`v}%L|dmGgqF~>&{`G z+xqfcv2;G~Dkz4JA%%VFFdB3&2xI#Q?Xc-Z1%)by!M3!1fqvI*(E{P-{>u$-q~dvV z8o5Go0A19zGZ9+hlGG>#18)x>_?YwP!of6sOF9!51)My@+19VFmi;fR$YVthjl&6( z(oHdu@$mn-6U&XhTI(r68*qzBI7+uq0lA!cW~u*%5kvSW<(p_#cxPICZ%u~%APVJI zPK2Fo(urRLviwrFq)Mi2fSQifDwSF{!_hyqAp1(toLs|N#;JLdcj&jI)oJj-UDtb3 znH^Q~h4ec?AO=n*#y%r;fJ@Rl@D{48a9lN^ULe#>-L^>^}_|2KZ2u>*v6H)-r555 zqZA1wa-6)!V~vNGx1Fo~vVm^p+K|97WCpg`AeAN6SA4h??{d!MF6rb~hAL@nYMvMWzxDA$;W>&=SfUe?AjS|96$EE+t}0w022cCLJI$h~SCTlnK6$Iw zPjsv!GmLaDs(LIzp>@&t{%g7c;KN}QbPkwof-xH1 z46H{tHAo3!LJWrVk~7yXZqAkOTvLFecvI1Z4euUS{C$okZGwF&qNk#!GS{vPt(UGS zOO`BM9djm%M*tx+u#{3`+)Iu0JcepATo- z|7RULMQQsvEd8YJ1LHx;WOGNa7rN2-AVHXi6T3dPf!LBZ@BOf}NwSM=aK|{AyW3V8 z2J{0>ct7e-?D`od0&+_WDDkMwxH)e014l^I*&n>Q5`L*OzUNB;<#I(6Sx~HTwX^G( zs;q7&khFNXs~Nn(gAYO$V3{z!vwZQ8S1{iR&XPhlU345sqAIHS;znm%jV$wQw_!AM z7|((o9V@>~*%TX3M#-dyRa%T&u$GrB1{#i!KgdZ?XL$>MbZ_x@5hScw&vubrJGvYl zv|R68X=^5jRt9qe>xAq?&|!iDbp_qiBN%l>CH>cZjBw=@{TGi%Gw@GPI7|WBVVx)-b5$6Mr;b!&)Ycak;t+3J%p>TDnDx@sDdEud z<^t?S`RwEoQ14Yl8XM3L8u?e|YE?9d`HeW^d3b>R^+^`;I8W8xKI2uM*rbG;9{iif z3yClBFf%#Am7+ykAD`ZZx z`|61!il#?G*C*|u#kpnO)HS>c+fhl3MkSGDeT(v%rQCz|eD|4KF6{4gnooN$-bji+qU#I%`Cd1@~R(2`^2c}rr^2WgEx-20DKxp39o zxk+E{m1*a7U$(#?@M(|!X_J(6(1ud01DA*99e4ub1#7WBJ)+&Dn=d*#L_+G z@?Is^t!Oe}Uu`BF65emP?%ivWHHjMekIb5xB5ue=gG#uccp&dPKwI{spuX7C$n`0g zW#oZ}47lMq0`z%|ninyYyAs`Uc-{|w#v+g>{GA)aQT!C~xmY4ln*3wt)q5U<8!Qa+ z5q6Sm%aLvV&a4Nu=zixB4<&s@u~h}MsfS{LywW$VvX-3MxYks}tSFtPEN8yv{akv! zo+vjVispVk$Z*Ak+f$0n-K@91+}8sm;3S*wuBh_L!=?aaK*K%`SI+oMkxh+1!^3BF z@2&H$r)%2Xf6%G=JHGS`vD7I{zgQ5?k|RR$aqrs*p2sfQaBwUoJkUT2^rV)BL#MW$ zHHkBCTm2aP}^pH*iu)GQzoxJqH8C{Bf)YdaknV-ics#dKh1xGk;Ujz z{6G>$$)bp8{0!Ew!GkU?>b z^Lv&N(uz_NSU9dJIb%Pm(E%UOI5f|{a~_}MkIHjYZ|fz;o30;kn3G z7c)q!-=ShkWQHlmQU*^jk*JvHB&g{CK!%tzhbnum;CHfw)Jju6o1~lrX;940@-V?D zLyF%noxmbhwAX7Wp`_Qa14JnQIsJR8Vn+yeT*M>ZJTSXRmDlhJH4OiBvV7IvLk-Kv zZPdd@Z^V@sbF1`L*db~RO>8~Vv8iVvfjeYwq+g|1NON>2cQfj$WGcpb_SLHp3C zWMSGZG@2@cq^rk&Fo?&YwZI$!5y22nuY9K$PkwP@gqjbx)?e#=)B+;<5MZ9-Bw56M zecJ}YxhWY zoQ|{1cZM)G2-p&9ZvYo!68S!m*j@KuL+_n!td#V4UO(dMLq;5AzOP&J3$rmMG>7cw<6=%Mgu0pV}D=$*72 zFv!I-5gt!~rkC+fKdJ9S5C2EAStVi4n*LTHG%MfipGSj2JAwl0wR-2f(o1A3-M%^o zE92!MTbLJ*Kn^qd%)5u0HscYxBp4GIxD#xSuxUc*ZIyidkLg=?e|VD2VoSl-cQOuB z+ykg8Mk6eu5&`2t+L%ab(<+UMHfh*x580W4bw2qIPM>;<4zb(NfKFLk|0TK!jCTLe7Nb z^*1!?CisZfnzP)S;1>H(je}-CKIxFdOOQ_bOv$)~M6Gw!0bqc?n+t1mt6NC5?7}p| z!wz*sgnSd8hnSaIP`pjsx4=4?kyov320^UPxKcReXO4O|T?8ZkaZJk06(9Eojc>l`vCye|zm-Q8eqg>`u7?Yc8E*-=l z1Y=v*^G%$}dx}GC#xz2olVE8K zN}Ik0lvtCnsk<#Y$VcBc&5V?6)Y}UbZlJt)N1CY5X7g^Lo+XT`9UR={ss~O7MS7KSnD@g8qbogL7owGR^{;aC6DK z5I{2eWTBhT1c23z)#*=@ZlBP=0MWd3cicLv|9otQ=GCuEs=W7la`@T0mH{p(9ws3; zI%rC;^G}s{Gs!FwaSQ(9*U*hyijY^kvYMHOffdO4o*2QSBl_Y%E7ut`s< z2$-5|W3J?X#Qww7LBZHZa9~Z_KL0P%J+MnBgYHy9gNQ>CL81#@!_~UoK&A?9HVmDY z=@&Pl$SCcNq2@T<{KF|D@oS1^@>wjqPm@atb9C{@D0KW z)J3vigM_U+!>6u7EKmEmkXUMs-MEG6de0VJnI1_{46jd}M0O0NvP>I`^U12gF5Q#M zJ@46aO}kCX*i&yx;(AVphKTnP?#d^_?7MfsQ)fuxZ51T9zDe{gpoC|m-FtHqcQH}3 zhRTi)u4H5DS4S8|pvX~RkDzhAcz)$VQ#ka{c4-lh4(upn(xEX#7Q_H6gy$YVImei^#Z!h(uRh?A?Vi~vKXo?veQDMVf znet}0VzO@uZ3o@tET%}Q z2kQSmKSDJzpbm}Q9;HGS$T5CLC|=%)=}>nk*{Lp-7hR#%84Wi_uvjf@n$k$*$Pt*B_v0Uo)BO{hq&OA_9^!)+$Lm(!U<> zyc2!%EPk+k+R(-nQ{0iUKr|{qE3V?xVjkVb?=&p(>A~bjd2r|?+Al94pp(h~B1ls{z@L+i|E6;yC~!NbVMcwPVZnxRfreQzJZOme1k9h+hc>mFt zKp`Sqyf$JdVMrxf+jK7+oD@?DJebOkB#Ep?ab#q(O#!2hh8w9bZEq#*HP*HXE~_Ko zjRnQNu;kw+|CDa;`j9C5wG(e{C#RN-kQx5)75hZmp0{XxOOz{taWafnAkttVgii(D4^Q2d83_22cr62m9T0W|yF4a>n zPnMpB7mhZAo5EXs$ZQQN+XiZQi&R5YE7My(2AM_HECDO7#l&zB@tv;lNSjXCvJ&eoZtOuXIBl-I+V}q55+D6*yalip$xyTiCreG`9 zDlgVRP?9{}WIi$;7E8Hi*F!d#`WByC8~=KiTGNA1U4wws_8_4D+$q}yo+}^mn)dq2 zeM!F?8~^rr6r+E8rM~9e1x{2*8@?M-VFC=4mUfl{3*)l_CwM?SDOtx7{SbnWz?Z!< zuyd9at_^+trnOE7O`=(5euiB3P80N|{eXWc4iU8U559>pnMW+|9pnNN!*s|UQ&<5~ zA4C_yg_z?-}zIH`44Umx58Wu=umB6rO)->zp&Q}y%EGr6_L5RF09xS zrQzeAP_~!jBc()wx6<(@LUb;s^al_pMqWBeBp~RzCQ|p1owry1{LKqBUqSlf-c|xX z{7eVIAMj9BL*f%ZY-^y0>+q;p!aA{PVOGH9E$s(j|0;SSYlkLVl%6Sq(;fmHgs(5)VBM~Y@rz-1=`By zD$@rcEnh1G^6(0A=^a9obFPtNX>hD0Lx402lu6?8oOR3kbxtf2w=G-~gdoncFxZ`v zQN5Oxatnf9TW`_WjznsNHy-AkbSUD5)y-~4QQ&oeW7FN&yuQzbuAC$=TyXR9)bo9lwLB#b&JjQC|^-Wi)LfQ@uEwjvVCuYT7}_Q zk|JnEpP&@}xYG5^LouN@I3poN*lyo>fBm?%R?}#B5;&c2?U9BpMvSMfMlZb)uf%!C z*DJXsgR5e$+1-TVZ+-1>FSC9>fXwsLUSyB@edGCE*4IZf@!*ov*Z2fbq!A!d3*l)Z zA=AS=@pgqz8jJP=*%^(MVYWpmkpG5@-tHNU>j@(<;h;ZAAiw)c+X;j7$+#mL^c>Rw zH9*S0@`E~d{b3`&DkeYIM^4|5ksiKqbH$572>0_Ti19w$$$E*QJCu@$Ncs~D^ll{N zbp`l>4;Vp9kxmB4VIwgTno@HC`8qWkMoRUYQ)^fqJqe1tX@WHnwgld<29{O=`C^MyK(qMdM$>M*wXx&GR_yd8%&TU<5$(^srO7lW@%1X_U%Ta?;@IwQ z`dJ@A++fFr#Ei?!CTnI8t>^${4w0ydTYjb^ND>dfah!a$usv9k!-h~@yc)>VnwRQF zBXRE8dpGB?<2lFjFLs?xH4WGx)QBb*2}9dmR~W zS5~_H;KOYQ-VX_v{LUuq1ehq%$l3N~u*C91Es_Q^#P7!wFkFTkh|PzeLFw>@Wk4MI zZufa`tk*rspUkM30kAJS$L7t7!CwdqteP8&fi@yJ19uNZ5`WWFmvvmTon*}ub!)Gu zVAhjww27xKj+XTe`;Wzyg@mwakV{AaGapVzbqVi=ht&`1_(#SC8Y_}T5YWkN1H+4d zQybKqtaJjuyaQdrt`i`Qc4vl*rHS(&{%c6uCE@H<_WKH1LhT(?VDWfT4nkRTI@wTZ z%MFgB1DEK$@UF9|EN40@jy-9@i94^xU+RkZ4256Gvbthx@9PM;Jvj3dwv;+dJx%vm zf&_>?UQ@@l#0^J#{AeV-`QYo=pu$#o`Q38Bem`e2PxcTs1@D#9gy_q5UUi4$J6VlRV8e{db z?zS2Pn;s5^gT(c)^!5F2eUT_bQZ3?(scEDzpV`0T0<5YCJ+>-oM<~x+4?Ok9Mv!|! zz=Au5q}G+x;0W70sOjx`0B&%R=IZv}h?g*5WnRH}D!dqP)k8k>WJz%WnDkg-`k$s} z%5Dyd*dNtL@{z1o$AAXiW*SSyK&R&>uI`&cWE{9Ri&1=WOBx%VTzwlgieDi&WqnX+ zPy)#iaIR$G$-cUvT7xYW^L{Xc_%gb#Ax_z zIem1E6Ik0J9cX>jW4=ue>k#gFN6>C1%xgVqmkjWl8M4Phk2e{zTZY8Lb$rhsU5EXp zGK7`*O-ke}%g3=F2)AFMm|aeyZ4t^gES|#&qTApl{?)tzo#DTTsAco)m$ElQt+zrV zyA@QCBA3m{i|^4WbK3@9NHfUG+a6TLt0TurzgPIT9hy<1gzw}hCBN^kP_l&U46kVE zER%s0c8r-AqJPOID1m&Nqnp3bR4@~f(1|jC=bEfsLxfReg}h!xE1RSSTZzkQj#yAY;d5KVZ3Z&*-1imD8DriflG`!Cr!fZ|6Fol~8%arJ^|s z*9t3v^gF%l;Y2$-qZg^(rV?*FEnm8&e7IiY1$1RWU4j3VZ{28Xk+hZ|T-OdwQ_I|X zc>Z@qD@E}(u4y5TZXY?o4dZr;whX}n5la1g6=O;d$PnQciA#!hqYogeTWN%)PE)gg z-me8|)Onl4sF=~$i;3*tRTZ)*S=oD5nH3Xvx|?5BW=U9{)|*o6BgVq-p=oJ3bwuOZ-`~4rPisU- zzPpddPa|0b|7Ry^y{EC1J;NNC&xju1PldSXcp-l09;BL!3Nk6(aj0`5?`1HLI#(vu z&Y1l*5J#goao-12z~F&)vW!eA_3Qo{r+bxapd=@Hh}%C{^!KH}4&TN#l2H3@|I}Pw zJcYqOjez85e}8d97HO)uvYfquw%?}tE6X3Nk~rx*070V;FheJcklUDf@%oy{qs_?) zszK3Ci4(_3DEKGlgII-kyDIur1>0DACSDX>=MtJpa${&aUuLX#-gFX4IU_b_n@{%B zNhGDoP@sZb4lx)&P+01lsQQ^W^n_9r^cB5Q$QEJ1dAc|9Rkg0fOHCVq9tRDFUU?5W zfReibDMJp<_$G-NPSdl}2J$ngcHKxt&=7205Aocfk7Xxb=Ld~j*;^8JKcNB7i>2I} z34@1k{8&TogeBZ<`)qVM_)<|>O}!fcGk1;O{OO0a;8qAv{BYds-|OW){>_7M>c#5J z-Zb?XDifpib>b2ej5*sOe??LNlO_UEA63gYa*|`RMSpXM?Uuygofj$#DWF=({v77x zUJSY+B6}K3=;4(pEN7*8gC5JwzZ6aYQljTZeo1I8sn6k$UZc!3b9W~ni{bOjnLoUS zlwAJ-q^WC?aQBgWjC3SlDkPmeY(>3gmBRqra4!PKL8h@lJc%GDAX~PIm^!I)Mu?nW zuJ4BN4DWD&<=J}@f!Il+%GgDxQ^9gG`*2Pv+*u-`=SF8W!57VPv! zWy$^fajET2nLwmcQeu(lB|UznGKyYv>g@TE1v-fWYP-*SpcOlep%SkO!lo)WRnoWb zhEXd4BeCR>L7Ad%9hJVqM79OoIUDg<3aiY|@Ga3^C~lIRV9W4mF-DhUeEaG#nn+*) z2DEs=skJiH#|b5$A-hCF;)SR$8yIxz@2(%Zhz`He;)Xh19AX#=IS_#f!uQm&$doft zK14XVh5S>)uYEX{;G1Tf$a5sc6qNr(I8S&`LWbGLsPadzAX6%x#oG2ljk{^jjCJ%R zxkh7$r__(14)qYNMdBX41(pNgNOO3v7?rbRL*z^oEb0GrtaoI>)rg%2J}z!|4`pD+ zL*Ge#sfMIyAQO&l``CFx1>ENsUxi+PXzaHPJdmCu*iX)pTAL+pIdd(s{UsF#>jLu; z13|!qvXBS$gU>Ll8zI5r6)N8Q6~<^8r_F?X94g`|TD$)We$NN*Pgn17TtZxdd6|VJ zURI?nEDy-!{=z>H)G#JO$)@y}#*ceGttRYFfoEa}WKi4_@cD<7G?P5`V~D2fDQsyD_aBV#9=p#2u8-+-3~h{mVVVNYaHmWkuGLWrr&C)^zv5;T* zVlEyxg<#6jLI1#E(Ukn}?RKE%xAlzW@V5`}iV-QHR_%|h`k-G25Jbzd~hLtUWanL zOZf0ICxh5(XmWK+tkD#>n2PZLnNk$bHk{TN|6(-2sJN%Zvx*x)BB4n)h(tEFmp%l& zqQNs_*o?x3Lin7s&)?bZxA!^CJP|@3#Drud(^8e|(DipX0tKZ+>oN3z=5-65_ck2_ z*u60>uq9CQk=s%KnEQH!jx`+#B*o~v!{mfQ4*!4H?6N_7Wdk#x4d>NzH$#6htvz9N z!5Q_f<;?fgLuwb^aEKft%X^wjC7n{8%9~pv92OQ!Q5om3!cAI_I%4$&JVSLnn~vwg zyLphSJc?LQxj`h>DmIkoy5{A4hJTO(4a6lOuC7S6 zHkMq4d>iPt#11rx#&Rrqqdr_$afT#Sot!Ew5WM08!NMHhZFxQ>PN_NfBAsH^;=AIf z+Tz%cJ*j40!=^Zm)U1yO!aPLr75@a18NgX}IwlalQ*v^GRRt0gJpYrz4gv*Y=}>D$ zb?BWd)&&3SUP-)qO=!KR1F zCJSI|_Hew_1Oq4J8{NqEu<*WuTOa;hpTld5X^)|WW+PFK0R+sk4xhrV%~1~Yu~Iws zSuDFY;8@KR1|VLX*~oD6E;nm*p0O3`k51}2VscD$K}I$0{Zztv@iT@Rd-A^`JhZk_ z$(&Qo-e(Fq@xK6AasUPacR=;!XJclKC?GpbUrY6{sZA$<28yrwk>)s9$A+q#!^Yv( zmytr}im#4a*TXkGOEi&ZlRas9x)lBUHy{U`La*wuZSs1X78eCkK?5&pf^#Fh5EmfO zn@ti=Wg8bt9%gb4!e>oj<`FJDh|XfqF8P2{piWLGgL9QN?b=QR3)dpxLqV&N9I?_; zaojyDo7k=g!s$~niXv4M4eg*i)Kxq}U#rDST4tIwQHEWf+CCbu8&OHQ2M?!Z@~Y~x zKG&j>bEyyDA%WJCNkGF|JaF*^F(#u^|DOn&RMM138Pt+QFw41(sWoEBJ^&~f1M65N>oC@U)hL%7>sk;zP+|ANAuxv4ZnCRiii)@^|tvF7O7Z5I$KoEE@63vt& z-U_O!;iQN-Lnc&|PTV!uTB?H^)c8XN8{J9MrAabF&fY2q##`g;S0V_{>F)sQ$#GmM zthS;ZSMc&@<`CUxfj5E1*&~CGozuFy=Zq~UO@sC|yMDNTm70*6p}gIqa%DJ%>^uqg z*%mLs0bnmGHArHAC>nP%8m&Ig3;GAF@XULrQq&X@art*0`?ZEPUE({MWGX7(7#@rB zre5Z8?{OAc)cJ_S*dUrgBSs3G)y@&R0kUy_nx0$$XIfJ+$OdkxrgXUhyx#PvBjTzVDP4816fj5C%U*-ie&lz8!Gy4CH7Qn5D_q_MJYi!jqp(N24#ZMpIrf=fC`J? zv{BpEP~s(!XG5fm%!2?^wdh#6v;i=&S;bE$5*&^j_D45_jS?)b99}f zt4Mw)1ux8y=txwP6RT4BVbdA*5h+lc)C0Ke&Q_I%2lx}f1D=XJMX_K3S?!r+Tg~sI zy`0;@c1SiU-flng5E;WQY#85nYPJ7Eejk*TH)8dK43$L8^h(<+G=PWXZSH{6RUWeR zLC@=NGZVVg5buMl_s!g6sq`^*=xU=IN&`fkUd4w1yRqEiv1wv0$|#l|!fVx$pW0JL z2yQ4`3`N|*%Kj2PCe~(xi!$P`EZ50Wl(T1v?)?>?As$yPkho3lvZn8Oy6`wOt0RTv5DlXYdYyroX z^+Jl;!T&|^8N*sPCWQx|H(KlCKbvWwNe#zLwtBaQG*R^7xZ*+fLzBqnwINwxx(}R- zh0O2x2iB=jb=a}^G>9j8;^IwTJepkt;|f}@+3<#NFCdq?KqZ-+2`*G@b1se@u!SUV zJ^QPZd}8deqa;HmeImi7%*X78ylv5;rG1yrMeomKdVh-Z*S?u;wL2Dyw4E5q^SX-* z1_lL=lh|OA0K0{3#ohvUU1hru-&3-s873Pi&iFvgI)nxD(Ql_CuNv z`we<;NtbyI2ltXXpw34stNgKk@(BX~9+cp*?0wXWYJQ1DMTxW$b<0>C1S%tCB}-QT zsTD^4_&SRNa{INy`nXL;)191Z%<}t_zjS?8sfPQzIBW!C2-S$Gw9->)?B_KRR&4)G z01i@1+FmfGtcL!caIfjAG1wYaLawQic~AO!icLH0XTE%|7zoQUk)o1MRPqzp%Pp!C zgmTz3`pPEXYL1c6!}Lox7y5Spph)V1^2sW{9cu`uFg$p&Z^hs#Ud{ zIh6uxs=Cs>Rp-55PoFa0>o2e4`>kNQBq}vAY_NNQK1hkeQwn$-&Y=@az=f8xPN`Kv_QuJ0E3FxV1{V{wuc29v)*XxSPfXU%SPU7k}@gj zGV7M$k?lg!T+BfVcF=hYb2N8^n8M4AFLTg-^*s8k8^ebadrJ>9ii}7 zUSUKiuA|b?+XMDzA~BW^=dOKRHu-Ua>tYqf*OzvSmcaoG_x}uh3O6UZ*IrTf=nJaP zh_H6zT$;Zsg&b8oS5+BJhYU=&t74`__wnFSwQ)@mUNQ`C!q`sidoW)99#;%F4$JTW zbXWoT2`1D>k16iDcL0@y7~vNqK`?xwKWq}8nj5F7h6OI9rouFj@E{UZe-p9s&(1XV z9loT0%kUes{Xbv8jKFA)QH;024Z2 z)s%2&JgGVy6TZX%pf^<$X%G8kMexE%Ff&Nw&+GFD3pY~T9SvVIXW!G(AD{Mqtdrh3 z*y%s}N`RhT<<=c_u9^MgyK>b`=3+9!7ufMAe#_!HNSgweuv{M0i~e1YtTo7Ii4LwU zq&hBRDUk9z(j->9TefK8H@Eb+gcPi2b$bG@&^eS&4{p%8o}IktF3 z$J?MBoX&93b20dpha^D*yc}J(xHay3JGfeXF^ZAKkvu#>h)O94ygsO7Q1?G-2|UR7 zeLB98HAzR7Qw7#{E~ zL`r3>u9$8@691AiYMd^d1$0R0ZlTHy{XZ|n{olCZ4PT?o=^vC~n;f_-8w>L{4~n>q zP1UhsyQ0aYJiCT~Nw$U%j?n$tQ5`_zg?hh|&a+Qg76*2nTOdqDnIT$W>&W0N0uoap zs(x-{W^q?9M)cJK|9w`N;7(%g+UPQ`X}JVVXx!jhteg63i z|0FIv_}l+V`3kyTD^bOgfXBOvb!&Zce-GH*?p0%pcbE(?0+5{JJL&Zx zh0{%gYzM_?fO{HFdR&hTF^6%*V!FcGVNBu@2N!6ETpP+JBWBy&KWvBh!E&G_gb&mi z(mCU4P`tW0ZMe|7p#^l4fO6DKAz4$KN$6K007s-*P?1B83Aw$?gw*|_ZFKxmpLgBO zw72>}_RO=2pQ%TV-;-qJS?=}YqnzZnMG=g3oiRn1wHO@KHei6z{uG{73ZmO+hXwWL zjngz5VVq4@-ZEwPunypc5?V>~j(&l*5@oyC}yaUhfnXuGjM(~Hrwb^=@za^W0Jl1IbtRf9P65JX5yntoATf*D+x*bB!G9932?3+ z8eU(F;#%*7_OEQ}1efwvhOEFkX@8oS(BImCLbkWjD=7;**B|TXWa`gK)LXlBjzyL; zdlEfYl>9IYVay_&c3Eah`V-@PSDN&6OY9u&RDbdmFK4Hmq2vTP56afk+!5^V1VOQC zFpb}Wfj@vSN-EVc*Tf+C_4P-1URBlM&G0VmPbc0OaVpb&WDm=w#as0iQoJ*&ko6{&OR(Fsg*L-4A7Lj2b?Bl`ZS6`PVv9ORx*zm~RsW%ZlnGa6c=-14vW?-@ON%BXcr?m7!-1CMCYVr}YUR@ODdYoB5fy zSbqJFWK?yk{)4B#f}6nB{}W_k&%oE~9ZvJwE?Q0oP)aX6G#_Ph|3nzIq@oFRZj$h= z5!MCi;xh1N2@V1dih~M2l?VjypF8_3SL|jz-2y-0R~W7KfJ1ZoRf`KN8m4oeJptKU zcH{^&9N>Huq=3lbxGQF4i_UQ&oEFo}28TTJ~PwCE#cd6rt1DMh8zGhqUv zFg*^gQU&-pwco{l>HZ$teFzN5V6vJsd*%xzBrRiw{}^fe*$v>2V(2}nR5bGKFctbc z!$cnd%SNvMW}*H~5y$y2gNHG1#DZR%S?3_V2iLHyU0fM>QG?^77Z^kYdS*WbmG*m1 zY7yH$CRd-qtPTr#x>2Va^LRpxAF zclIKikoB|b)kUc&=!@2bRn!^qTJ+obCtXQsM?3yrrZs>((eD8m{=`}O8`{enXoa@m zyjn{1i!Z1N)k*L4j+V9jp3(B(zkJ<1{CKP8i+^-()-;)?4^a84&4vuY;(_tw^TIxjY+et68%VNG}laLse{Ifb3#8+C66hRvm5TsXo% z+9DRfv(h)4bpV${S5?9{RlS0Rslj$|v>Do?lXSEwB2tD?;d>}V(EAE~(HcckxL9R^ z&bSQpTc-SzosDB?dAacL&T`a&(Zh>==ID-|5(3x+tCbn|^iOe&!@2RPn~p0E$=$GhaUqgA<6Lh>U%Zuo|nI&!dgG3 zHh)eUW|eafL=ij{eFkPeW*t{26eq`F8G7g z27_seq*@G-a;2K(B{7&9R1CyHf5pF}0r7@TflLp>GXR9|=k>k+DeVZyZ=is0?tNI>mSE-qUgCIPnH+)R9ruZKIGKM!mkuL?m1Rai6M19@psnd zf79W}9>TvltJRA5*` zl_?Q3gKvFWjEE(DFaYe|4WRnEkUHU333$103(5!dM2@e57Gy^6N0ctV28vov*69m> ze@$7EAWKbOZvR5aZU@uJjbYdB#@HBqIK;;4(YR$IYdV5XW1%$HXKJW-z3cwKDu8ji zf*TC{znj(>-b_NX5g=qux0$@06)Zz(fUNeHw@rei?A_c1PK@)Pyq;lE8zLqh`BYE2 zLC|X^flJ6d$*@J={=31qV5TqkHa{_?M8GcA1iAx20X3dTRD!z>=rZwl1?VlBXA zOWV*G2!rvwdepS~QT@Azk=C%Vylc5bf%9a}BE}AJl-V>zPBCLi#jvZsHe4q?9a9g9 zVY%tT@H%W#h7kSjrX1BUmBr*}NHa{HCr?*!+ieIqc8(UD)a~k;OO_{;*ey<65vBlh zuUAZH>T3ev*@K0WE-^dnX8>y|&p`_jUshF*Ih&2(~i9BRXgC^XUb)#QylI8})g zU2Lw|acAV~B-W=$Lc>m<4;zpcp=m=ij>}TC_Xos~8M~Zef}hgo6z0UAwZ*a5Dm6+J zSHQ(@i;PO-2-!(Rdfl~pixa^_4`gi`0EV<=dECh28H^wh1b%P_Ami9^vT(4autb6R zUpQM9J*CGivj!ACf%BxW$+-9ao^HEQP6TJ9wN_c)?>pbB-0o;n&G&885#BM1&`){Y z=_@E@9{_D>pzDKLmonUZWtCBbkTfM3Hp(n)5u{*X zqUDLArze27vsD^9LzyeN6qB4_b(IMN$!`=8x{pVyzNQ!0_9Aztwu$MuzQ(CM4=l>g zmhiW0O^y`3+Tg}?Fv=uBqq~NK!yCBtf9(QQ3{5qy=n+ANHUyH)DWc(!V_xkz$iW-% z+RE)kY`!Y0&Gsbt^2traM@~=VOF+B!)a7wX<!{|z$Ue zzPSR{4SqhYlrNM$QDrQ~(}tH*ute6Hw*croA61ld6!Cv$G$w9&U>r}O!p9uD5!(QS zYQ~Npq=5j#xeiDS5ph`UIKEr9(JL?-*4{fA2Es33TUM}Q$U`e7$t zbmCKT#kxIlv@q1S+Q}6+&}S0`2YmDbT~D%|aGRi8l;^8Y#U?=(=8)T%B1`~WKx-sg zIItS)4;nQ6l8i-0C1*s}*gY!n>NC&ou8#qorW`*eB*U**xIt4ii`H2PWil0krFnB) zES3AqG~p1WB!l9n%?1SCVX!YRI zGbAnGD|jqAH}hndE<sT!UP5P``U5rD20x=E=SB?xh-1ufScxe2P!|- zeo`>dkQhKGk<@Q0b6qE(jjvNZD4_3RZ>5^4eXm1+}H@`GH0K^+WmZNK~J z_n(8r^KXfA8%0RtJt+|(Y0JKqqp9K)w3K7gWfcuBX0!SQ8NFBO7=LC$rN_Hw)gW-? zqN2*Kv33AFmsjE+Y_We%W4q~TveJzx*LJc%w?TDS7`9nnVR7l3&SfU^rlrDkCWEU` z9eSKz7ayTtZAF-(v9$>97-UB5N_226VJs;$La#X=VKgX`DvRykC{HSyNW4ai2DMU) zmkTm`$(l_og0+V9`VYpK`G8V%o3aO3D-+zVgl$1^<=bvB`a&;(RY_CA6Jf%kyt;+M zomr>wY*A*|A4m!Fr{z%dac(F)*(}u_f~mifwB5n7?dkdgxV#pXl6F#W_ay#}b55nV zv9ub;mY4jaUxr)yf^!+{#2C8+xtMo*Hw-I4=o93upS6y?2z26`VJ~{7{fkcZC%`07 zDeUv!-YvNs$kOg;Icj7XfK><)yijA8Mw}a4Cs>}_S-eqqzZeOO;~aTwS+KgdY--IX zsO|cL?tpKh5kTutP0&Fv=TU|R-(ffL#VXE^XHgA_>+)#y&Vh(s9}e@DJia1dV`Rpl zmt~JkIbr##P2ra43j>z1v+}tMCMVt6gnsJp%DRaC8kbGnu^KEYuVXASIB z+OrFVi6h;q4=k(ic{fXA0aQq=Y0}~(CFL0cSgI+BV5A@9TiU+$qXjx<%A&jj!qh8d z!Y**$b`~9I37nl;xqS-W0Zm++P#O|Tn-x%9u2cQAY za%3kX?)>JaGC_gtmeZl#e?=GF|Tm1~n)ZkyJ+F#;-$${3u@P>}>ogs8+K)H>om zU~obLeLXoTY}`+dt#@wD1>oo;9r#4=e%LvkOMIl;B6f{EyW5U4m$lEIi}FBH#kIpt z-R^e@4*)&ol4M*h4-erd6^P%z8?b}$Wsi82wxb>C+OCyY#eHH=*#UN;gAocg1B5;L zkO<>NTkWk2I$MyLy(O@(6&vc$$e##wLE(T+6FQF=)r0F)!^R{WjjXp{5*j9ckp4=z zpD=LUW7WPyHD!Y;XjoPDX4T(I-ra~ShPO4Hf2WhIz)Ar!{dxn3Xm_=P_k#?Qll$Jv z^P^rGEMLE&WF5{Y=ox{q<+*?Dx3l85a z2fF)QuD3PiPdwSGS0{B`M3!0BSY1;7MMK&w{B&!ZOW9Ggf*b#6JfUT@I*);QD;XGt zbmNAR-8rWMJDja=^c{+Vg9qqJpM{}tCYUq`=fx%+p_R4C(c8%S#=9GjzpkApS~hSSh$5g zHW;P;_&p=XAjr7;8Lckcv)*GvaP__T^CB`-WU}u=_1~cY8nSU}EVf)|ojgv*?6Sn| zhD38X)INhAwouhv8n*Am?^uJQ1wHcnVS;^_M;!Ov4ey4CM=;z&!VpK(oo)$C^M%OK zOHG*kr(`exZIEuDTBzY=mn2_!4aVvT*T9f=C6VkN-!ESMSYp5wg&=XeK_M3Gt(&3t z6tx*>I&=>di;8a3B&$q6;lz@C$e6Z)7W5{!(KEj0Aju6rxQ3>kFq5&V($~i>VpnTm zY&+o(MkT$V7}dQ0Ak5%Q0v45bd`QWOiBj~QO+BOoZnNImz(2a*5}8R;q0-v!s3x)I zVU40|UXW;4CDSBdk6)thY$`No2xG>x1^roWUJM;K=V#0nOsslo3+eA5J^tPyFN!OKBPov zwX-BvQwtfpv}l-@2;g4mqSnh2Qd$S7BiBOsi<%q`9o_8*Jv)9P48`7_59hDbwU^7b zlU)t_J6n-CQ3m<Uv-@@w7L^d??YN^d1?EGtow(dPFhi=SS&Vi-da zKTmUClrSJ#=#;8}u1P?`Sy#ggp~oRMq=M>%EUM#ev{=nw7#7;cLslX%?c9 zw|`l>1O*5_8Y!kl`0^#n_fzOBs|3kspGTbg#2BryJs`QYq6eQ;FSsCRf|jJ{>V^kV zYuTKyXK2~`sMxXU!Ge>sbcWn;c+6}xqGvsLz!q9-= zRuB?Qw$IL$(iwAIqTCA3h$ZaO`+!5FW7|&3a%1+%R>k&t9p!9KfB$O0?1Zb|)c&Cm2Z;aq!`Tmp!Vz z8KP21*`v55zVgo+w2C2AawWn(h1)FUwnjY(-1k`m_CT>Ghcj5f|EF5WdrzlvV_mx_ z65}xO#8d#(x~~9HS8jS5mQ`K?m!mbQWGJS1-=#vy9)M~~uSNL}99RBml@u8a>iLt*L!tTE>g+sO z3+OW6tLabytM~%pJ|glZ)=|0d z@5qTWMDvj_O(+r2{^l52pUuDiYC1hvka#rn_-8#oD z_x(+0HdQ()V|4Trb-p$NMI4a;rSA5D9;^Gq5;R7wIscqV4d}pF1_bH?Kax+C$U7D( zG$QW)?FcN`M9tvQGS~ZHHjydEktvp^Re(VB0>yx!hk+Y zkRvrhksTu0XYF4(W~onskDlNUBr;&Bi{!{KW>I^xNh4T)k=lLwo~s{sQ_cw7o}vPG zwcxAi_)7+sTPQ23f;>%9I-K(GKyq~Kl-NEEcZ6y-T>Tp}1&+4V+_J{~7Xo^u==WB@ z7Orb|NX%=|uRO>PoH8=<^|h{Q=1t&S2p;bC*`&_AZLIdfb$qfIU6s7dwAV*TcR3lV zn$#A&dRZ)8eHQE8Rc{jFs1{%kuB2uAb9)y<5&4nu~PF6^f_AI|LVYwUV8X9 zV7$b<%(|z8!w|Y+McsSM{OPB{zF?-;4j#~-0VN8m8Tw_VVWEWFu%TzdWFK>18OC#M zYJ8^@kR#za+Nq=i{z3L*p<=Gy5Uk=IveL-gi5e8w1_1S@U$+va{1hU1t+givotD?O zl|1xd)8W()!WJ~7ZK}&^agvV27%z7*5{A%&$b*n@QdJu9^g`F76g64jOg}H$R2Ahb zu(Q=TdpXXwL5%c#WUbJq{4?BqZRzSNJtS-qKh(NC^~a_B0nF7Q<(F31Kt@IM0+Cc^ zc~5w=&t}iWYndf$hwOA3Q*dov1b6;M?<|)>3V67ojqK9O)Y|L_ja!fqt)DSF`XGE8 zdzsuAS;(`t}(-=~gYPsm^Bb%+3akY5MC0A|Ig1i1^fG-qhRxPZF-1JDwp(s++VH-`Tk0oMJ6Blr>s4A>|K|My9{DBRVUE4HD#k;;$ZQ zg&oJX`1ywzc&NO@9qMtty?r93)=w#X%1szTmtdenBSEE9NNxZ`*g|!~*LM?DWy)Qo zI6fCOZ>aUjyKFiEAcjZ?NQu#exWpqckJCenp0AHC=EB_no=ujToPhJ}MGo=i)#wtp z&Nj>~AXH}BS`JSe=`q)n(p*{l^D6x_&(e+wU>-B}F-)nmF;mKbI{J)&`5Tx^q}_`O zdN69@_H?&2i{;A|Oyu+;m@)&flZ16zSGu!ycz@(sGeDJfsaOPF-UH|OQxdJG9A)OV z0Kh^tRhX%;jaImDK%nV#k!3*7PK>afcPS$=d z3(hW<=kx`aNAsUaDA&ERow*wKRS5K0*w!J5JsBpUs7FPuSLaMkch@g5&ZB+b5^k}$ zb?e^BO=os9m3L$==MG0XI4tJ-&!_9ZM98E%p$6UGOeZ)IY(@ zA(rV7TwiS;`x4YIx5K|dln1Ss%@i*5*vY~(M0$_@sj{=S)cunxSEfeH^Q((Yo5x0| z<4)X`bVKtD?sm21k9kd8ygG@I%LWCWWB~MpgHFQ(GWe1|IE&yI+Q>uye=gsB0ox}e z)i1lGGgPPbhP@q_;oZr=0@|q~S)g^LYbV<%)o(oQLW*Z|LD>1&GaI{fLQ+T*Ax?j} zR#0&SvI0Ye0iwUkFX8%T?u(&wD5{wI9@mWi+3_JYM$y2uQU4z&9EU`g6o{xX>t5Kb z?&pKcloO@GS{?Pp2-wMmeQIV~zAKruxZZ*p4F!b(UVrS?R1}$Jh?{~Vzr&{j$=Yyz z`InheBrk1k$6#yp&qXwlB}>Z#jy4{P@02URpz|f?!9$~f)?xXqqTBiqi_+n(C3r!N z))PtDOW(#@SqZhww?n}$-IRRv|OIR%ZRf=JO-$m8IV2dpIQZlA)`3n@OO0QiSf;niU3C5 zT;$8egO|+B@*<3B_OXy7{OxJSo(Uuv;?Wy1XD9Tn;3|nXfQL$e;)tNX^HJbz)lJ}m z`UQj!LDK=&(X7ZW`C^*CSQesS?(>Xys4Hb>ljjPl-?oGd55>X%~ICHHo@hJ*tcGe%CBvY(^4+}T0(}-K> zEuhu0S})LyVqf&C;%eAD%gIjs^vzS&f;qx$ zy8WAc&zeVWk?Sq{z`~~~jxji>vK^ub`x{W4aUS0Zzz@*+Tr#DA zrT*SSTgP|l1LpxrB52~1l~ zq0EsfD`GO8z+NXt6}~1*c_7xcIma!ydf{~^+|3*t2zi@|F4aVbD6)z(k20Z+!cyzr zpEc-!eD0)TRaI7f$)LHcI@g@44^((spmQ03AT0{@{ z7XNg!aR2vXh%E7?^jFP;<%plorkx9ImT8P@1m1(AW-m>>K9I}#_FFBVC4nHaa&e1S zZA0Iv88*`zx#uJ)br^(5xV>nn|IT8qRT8AH1|MDFKTnP{RG%^8X(42|gH7Ca^93~V zDlX%9UU(2g#F{HQPK7~((oUw4dkEGy15olkahcnj9~&hs37@Q^-TdY4%e-jd z7dfIevikH8lFJ=A*w2)L&e8zjPfPf`9BD&q;2WREZK+7t9Q9l9rcFE|$aedxCkb4a zC~|>Iz~xuYE|A(~;H|WE48tts20bI7kNQ=@PC=5Cm;1Ie>R}@$|AbKMB`RIe((h~2^-E~9oXSpi208y) zzU?>BTba6PGCsCjHW}VVvVawEY}uNpmD|OUWau-PmSrNgQS=-uVU$5sasPsveVOd> z@~==jOArS2FErr&D9;XEq3HpCXxtL5L(Dzk<#05pWk7J!W2@Z$(Ip->biJgJe{#<9xeD~pjG=4s|Bu} zVE;E$Q?Sf^7{?zLCyeKIhTKyx2))Qg`n+SBzbL&|ngE6~5OZG@AVIhl7IB{u<8BJoRUV6l*dAfB1ay%% zfquslZATx^Oy_F>TX4+`0et8{!~c47AD^u;Ov^?I)_8x37hcs(QnJTf=dD49CtJ1) z)i+GlG?ht>2DIdqs_X!RfsSX9f5o#TUK+M#Kn(45c51pBZz@N*FT|hq4%I*J zO$u|&w;wypPlvnz#cv(htfPU^0Y;XR;LK6zW62JDxR$nYQ0qtU5uWO}$c~yZjuN^5 zfZON{)*D2To2e`YuJWe}HoMSLAiU_gI@RZQt6FRMEmFs%-;eFqwU`O1tP%v*;pLLK zo?E#J%h|S)Uq(O@c(aNa;AJvqd-M8!9Rnk3unF3}_IdG;GC;6$Cjq30bK z@wI{z*>6W@PUWXWHZY{F3me*!m6ot~my1$u?I~~nBs%%OolNVBNFwUpjeX}k46bTO z@@o<)NT^yeLCmOwjbfWX*bDn=<9{+xd`HN2{!lF|j#Mpe6o_;=`7=XLCWxSH(Q@wY zI^$0E;EU>tI|)55BB{#F%AHdiHKdrZ%y=KVH+j7dif+*@9K^fkzYkFV4#~kG!32F< z7SJ0qoE;>YPXgdmtL_+DBz82ZeE!pDXLl$kkc;j*f?+l3WvJZ5&Zg0qi6hH6@QfS*) zd93C_9~=e(!xL98!7+t?&l}}mmZ}B-mBN~GaaoDpUVdtOHeWaos(xCqPDt|sar48~ z5R>?1;!Bi79$HxiCM^6K$DjX?cXj(fpcA7}RryIwg@XM75c4dcCfSA=>6KZiQoP(ZH!x>Sm9oJK zgZC7y&fc2&Csh2um~v&;x{^&9F)}FKUqAoRq8abP+PrR6jK*8cGx|v+o$ih?^+g=$ znXd)a3#?cvQasXEgu_GE!Q;%da5!PChC^@tcK)MJkUMt4r$MfYTm++6Is2QgjgOkSr2mupwI<)EctYU~1Y0Kh^WLtRHZqHX8uMWo9o+Ys*iH16 z8DU?hW5O`}KV`W~xZ?&Bj7m%>3L^&N%Di@)h`nkQyMm(&YZ>j?ornKXu#SZsgndmQFaaqCyY z}DaZ0EMEAgX0fAKeIRu#6w>Nw>z#IM%t5~XW zhS67T+F_59UwvN`->li^Y@;dvQ)@Wr-pZ9aCo8^N8kJA6t-?CRa~uO&F@#bEB!g{i z8huj+yPY+rh~{Bctoac6(0O7+DfJ_1zyTbR)122jRjj)?q5Qz4ewOTQDZ8NGR65zN zaW@>dE|~E-CW3h$^WrdA1V^0&y*ASamIs!^3+OD-{AfRd(}c#%6+kk1)a9!y3LJp( zaj~@VAKPuN^=!(WLk6sG5oe&cbLe@20hh*M(FLUA- z{|&_^5l~-fmv8VXU+gSy@QNa)Y#a%w|LHmD%`=`zUP_J`O}lBa zT9k;6T_Y6Bk9-CE=a9E8j0V6u?2x|XvX`mSUi<@&-E4n$C* z%!GcC)bwEA5r96#%OLD^W(9?u^xojWaK7goigxTiyyatSM`GMc&hG;(+SKUDj0Fj(Fm{Qqs z2fmAR+|(!ZP#@K15AN;)5sO^}e=Nl(rF)kizv=iiosST>8?oynbB%qt@m6Itv}pI; zo40`D2j`$FezR4#M?zTMo}lOJQ3F@m3sVIuNmdhC%rnSrc2Ru4AA@`C&jG^#$?9ZM z)moiplj}GfSOLJQEmB54i4d}E zkoPK{B18vvsKEqdEu$lcs*u^6=PDhoycyj*m0Z}nkZB>{XCIBGu=DmE$H$QEC2=u;2NW_->k z(>A2OhNDRL=i>6EXa| z=sSQD00t4*$rRoQ*=%TJ+i&4!m4^ z_EkN=^S8S-(E~))y&kAWuf7>wxi?a5dRsUIq9Q5I4A;SMie@ZHz3q?oPv^!@NL=gu zN4V&sV(@~WwZU6SfVG=gN1K$c|3(PH_4+DzySKn;u-yE|S*ta(kkacfprW{gZfmB|&+r~W&#Eezc9w9u>_=|U` zhurB+1t7bq;KQW`RYNe&+}rh0i7@s(9MDOCy}SfPQgP0LCuBF#&p*;FO)99YGl_BZ zA5Wb)vSim)I4$>{b-chvl$GBT-|lfrv7uS2iYq}>U-bL%TwqDS{%Jzv|kh&110 zeRJ>!xf}B>-O!(GzU5n|bYQ@bs;bdu`^r+IEn&Q5USvHi_ko~u=0Ey>K~Vw4XyB9J z4dIJ(e@e>P&kjka)vt1tfOM3EkT1Ttn$2_X$~fp=_acVql?3YJ$1HcfY(Y>F zlT=X`c;?g4H2wE`-NH)QrLZio{oWYM*O41ICQvr)|H#$UHz83Q3;I)Ha}V!gkEG`= zJX&IQer(2I_39|hIt*4^HjjpMTYS?OMb=pC+!d;jY0-_3Gl)O1I9~C$Y$d4~I?J{ukv;+t5GAce$-ClI)++f;7hB$WCc8@CncMbe{5`G+ z@4Q2-v<&H}$rA!DEFKP=V(h-tx3@oxtlncNV}~PxbA8q3MXZIbN(d)v{XDiXA(drs zH;FdDDRH1v-jcyVmSn$yp5f^3INy;L@xfdG`K?E2vZ zn!uug4wH}4tC3m2&83q8Shu0cuQIE7yiN-Fi!Xwx(NdV}Kd|ChM8rzk-$$TE+nv9Y z2Yu^{oUVn^F%YYY4_By8|0%>Ruki0ATAGhcoCRPzwI_4$YGH4SskrcZ3*A6}iC~d) zSroaQ7djX?c&y@YV`o%Uu&~m>=i6V=S8J|HH>o^eQ9tFu7UP4VV|Ix)rAt|G1sZH0 zjgZ_Aehl@BUB8>)R`8C6zx2!j>se(w4C_W{99uy0q5*gptQMh@*qSf7aq1o~d7Y;+ zD0&OcJShPlz6;;LQk-jsr-#oTF*)xL#tbh8yy19rrCp|5GuKUk@T{wSk>h_8QBmAP z^_+26@Iah78(%^TU|e?!IBjo)suBm?zoIkK9W005L4}~`w$qenO;3&^y86Em!rpG- zt9a6kpC84DxEX@Y;O$(*xjr$A6V_I&<~(xf*?+%n&29Ja6DG|HFHuQtOD_b-%U7eB zp*SN{>rKM{gd#D?7ZDghkEG#B&m@Zm&}3G2oDstYK2KtE23K{CNtU(;D6@*NlLif` zIhIA7Y8!uG<(5^ZV=le;yR_&%ieJ(m?cVnAfZpkO!BtdFS2BsnNt-Y80~eoIYHRvY zg>q!L;?7AQ3EZhdzgGfD?}=~8UmCm8qQy=@MwxQw9|S8nj8yN(;>e5IB`B&rZ0{MST9Lw40UdQ4DO~60OttCcT(0Urp&8b}2l@!| z>19v#0*2I=WuJ`fYht}W^K>^^Q6#hi-(G?ycZ)pqrZTWlFxoEuhf?vm>nmXJ$hg+0 zq+~vhRviZtMNgoA5e9VWpaXYbH;$E3G$pZ zgIX0_1*%yADy``E`RiO!Nc%@UuTA2t+BDL+Lg-olIP%g(Txyb)An;x7Wf1$8dB*ec z1CF8&ZA!fa5g&n&Rt5)kbE}OaA`8RgC<>pV@Z`yb)tp#vZc)_jO5?DBKrLA_++NMn zYQdAg*h3B}HW}c`56oo|N1=NlIwUM`xmdZZ$d;MVjMxyzEkvY3%$`@6jx16i6{~QS z*v1m0x_uyd~fGzjvd<*EV}C3EF#g2^T=Y;#|^ZYB4U@19S;nbEub>R2oAks zaH#*b0ca=eEw)jDR&QXpyr2A!o^94B1nHvqkRuu?Vi+Z^W)rfDC@G z_Hr4;O!n2NX#q1!DV7w2xLHVZe(_E6y|o>}HQNAuya9<|YD zn!lNmGRbA{2AcN24ENvo9onReZYqUcfq6z}4+csUexfv5>(_fzK8PXzHK#$8mB?as zuJ6igD>EN#=gR50)f|UR$@cNv%Hh}GZ4WGg_sFXuj6T(Vbg2wFX0k^AX#UnVTIuf$ zego|gRN@1^6T_T*T2o`6FKMzSH0qzY9s*I$5b!8^W%qAmCKP^1d^$J|&N|>SVhs!| zQ-I>E{r0*1m+Z)MOxo!LC1RBwF1KD73!z#E@cf z^RjcrlDU)&-=g$W&ZCQ8n#&7`_au|#E=9rZ^DQs?(;%2CRlf}!No55&T$8TChwuTj zje4@l`>RG&nRThkE2s)plERHYcuy9FFQeMjkRjaf!H9ngPZJvK0q0K2u?Z)PV?JVEG;B zr%#HmeEI$ss;xj&T!C}7-xi2c{;*P=L^L1T#Oc0;(j&$-6|m+wCG@ zwH+lF{fC(xvnMe-Yq?zUjk#kN19b1-&Gl(W^5#K*D| zJ?d1$0KU32izHz;y)hSto()UFdAKD~PzY&NCRdhqO8#N{YR?QE(-}dL^y&M8qgNOa z(x}ZgQB{hA$rxka&Hf_7$Al9NCz0#cB0?(- z>5#xWA%O}EP51xc{e%9=R!vCqxId0|h~;Mh2L9{ORgrp&@YHDMZtqql#9H9eF9jgj zybH%k^8{uLbxs;$pZm$yaj?bxlM1P>=jp`5$57A_Kp9+FZIDm06Q?J*?N)I*7a%(r zpy7!>tcy0WVrH2FvU*l#Nvk1#12dfU0Y`~t7FoELpfx@SZ08PXNgGfJN%&0xfvROo#TP#bUiYlAI9#kEXq8Oe z!3_uQ^0vkxEOy(?5LV-azjE3=?v9CHz4v2559B`07(mgY^=IbN9(|76CgT~I50odO zXzvh6lWyZ_*uA<0;_6KLWW{hvyL<5xMh(`X0#|({g$){A!DwyheTLlR1`o%~=^2K%=9HC31SE1Qjv)HeZP%@_IlKlJ1W z+K2n@5pQa}07i;X21Ma$uwE~xM}1UZV<!f$hj7^R#oK zJ@Tobj(fDdMFL+|NT}*5ldiTmI8EmGvzqtv|FN`4h6*fWBqjuI_Cn-Ffq5~4qjmUy z7dEmghF}9GJkwR-$%qGSoCEcHYkI$*)m}R+UEx7x6dSO->{iT4h14ms&%=#$LtLEu zMZq**CaKxp8h&6P3;c-9EPv{UI|iAcBkiGenZP=(!^-`?1Xy}f5ztVFyV@PTX+S$* zF=!pcxFdsvkAJh#!ip$}EN)y^DmwUqzC~Jov08xjhQeTi5{Im)cPv6kDY{ZAZp;!y z#oGsoEr6WCf#i!`yKRI`wP?fZDMjeVHzxja>mj}jj4T24%*4wSlf z9TRKC+}A9ewotCUDzN;Vw~-!r{A{F9zyZrC1`El~cJh;jDB}w46ld*?>r|0IJ-%kG zHB4Cd1h6Y{7d-0$`$(W2kKz6x6@H<`>9g_75e^b6BS@0I^gHp{9X@!RD>W;3#Do_8 z&+R-f{Q-0ms~59{e%=WHTV%R(xhNw+yNv|??7lgO%ZjdBZVp#%Lz8Zralv>Z4q&yM*o&K|)ec8-~gw z!OQ98N(i{u2iB`&Ugm{-rSWFt=|`2O_iIiJc$U!&Q`wGq+JGrQDb%!)o|a(+{g>9 zcB_Ayw*d9V6PDP@K6Cm^7wy|iGckFYW?Dm;Wh}i(4KV|hCf~0Bt6;@SP&$1+?v5Fb zlmRon{lBzs8pAvYiL(d`H!ngrR+{$%0b;ozeEEWnv)^o}JILQyGSX_@Gw!eKy(;5( zQyXqan}PY)n-jarS60f_`=AUCnBR<;F~V7d_93?ytLNz^U$vXdMeqc~BDAwxNKs1yJVJ z3P$Q}YTO&NgnSObpE)FqtFrRYTyFkSFxa9!Vvg>0-h*Ztmjf58GdS$taDRH} zetN`<)(cM&0=W<28bZi@roCR(TZE;%fB7C1*fi&FqX@#h>@pD&KZ)IV++KEU0M4V) zwm4L?AIT1NC4XubJH8gx;*C)IX0w7C_Q-uB?WGlA5A!XF)5b4&1Kvn393cqj zt^4HZDBq4GFc<9`s)J?L&X(-`7&zxR%eL_cBsCbQ!$KTHJWgZ&@H?QL@;0qQPxx_f z?mJhgBf!4$%zW$iH?Pe5DIzgvu&$^<^&mv2#aXhgU}Z>#YzfyiNj0Ss7Lui3(j{&R zz&1T5L;_4>uAbhxNWr?K@Gc?E#2>{GgQQ-u6(Ln}Dobk*^NR#ZFwL_&23`hB73@C} zvW4r;5vxCyirlrF5)Hp@Jpfsgk4PY#Th06Hav5c?JMm`AZjl~=mtKd-3iS%Qey+8a z|A(kjV=tbOF+5KFaLAnKJsa(6wH*tJN9zvfu^$H?Wd-zq>IveLp%lkR$S3f??-n21H5Z0w>kcs}8fa z&(~V;%5<6U2uMYQlD9ITZxCkIh97rp|FfivkS7FRvQWQ7HLeTIpN49mepTRi{~YO) zlbkBOYT2k7IwO7kzVyX^eub8izUQpj5{jh#9<3kUlmyQ_l-7F+8cY)bJyINbSRCLK zU=UA!%0Hq}H;X^nEzGnCPb?Q-K=(;(?z6R=9gAb6M?u3Tzi0`LklY-esHdlS3hRu! z^AG9Hv(b!$xpvE~>$4>T>@qz3kUX^7PD8 zzndZM18C3|5~Z2|?w(x$p!q^Dc4h4kV$g`pp$df}TKS6OCeskruTaY^+N-WU6TTi$ zZ9|l7v6`z6uIY_1@guJmUSkPx!?8#29^g{59z5E&xd?B2|I?9pGG;Z0Z~}C3&g*8e z#+;(sAp4`}diT?vDWoUd1SYi%qb8%nl9FZ}>`nUC>@1k}FPlwgQ}^q#aotP9Y(Rvo zI!>Q&NmF`MXA{2VD%}Wc;YMhn8`+^3lO1dmx5%%dNV>IGV-40rjvOme*-LT{x6_kr z4>a3pEw3$#i1p*tF}9zlo1U7Kw}eB0j=CBrTkumy ztbz+Jd8bdl-4eZOVaH$%)dbf=zYLCT?y{F36A0rXEY_iyR_gOjX+e_CN{hZeqT0;>N`B-|1fFBINhsb<0jT#eu9IWzb zg>ld7gKh1n-HzJjq^djQg_ARCbP8~eFX#p>B}5BPP|08z;X!D9<&gzQzW9wn#B{hR z1ZW+~PuwALrup*~Pwlssq*Ppa3xX=fOuSSPKVgv4hY;Fpp~0zx7gh}{n9h<)6u|cz zo~BcHC9R~T zwgIR|OrQ}0oEV|v)h^##IW~jx;ETWZ-}%I}&#GVK_5Jb zL*i;(`=E$4ia z2+C4OE_!{S0VTnA33w%|r!@1`6UuXkdF!@^eJbdmM^lHH{}womuCX2C9JQ;^(c)=1 zmwixUUN#}TCd0m|c8;E|ZDDB!A1x+Z$I%?Uwa!yB3v`+J#=ohP zDZ!r~h#wK^vSxK6$#KRqEIEUdW2SQXujh|&; zMe>7HqR%Eyyf|`-Iv7A5j!rSkJ|7URP=3LDqm$KMq`5r{6Z($kY;;cpO|Sf6ZId z8U(ralfU1@={b#`#v10rg+)KLz_Y85^HO&yzuRO|R~oS@GqX_2rQs<=X@`+*%3Q!3 zz2Qgk5KqE+2w0ilIsi|uwUH-W546TS!!mZ!5PfKxlPSrvs2EouF;7P53&6$XhybqJ zMQ`lg@igaN;hJDw;%mtMDDZZ4g4P{TlDrG*C%qt;^KyxkB}F5Yrs>uZPlGV04!xFA z3vBL5uSm;QVz$xtlk{^BhZZ(#;H=n`--vDY1P0l#Yjvgp#K*+8MN**aLqD!PEA7~) zv{p2hkZq)}($8KB;RMS~2Q{w;oe}SS{aV{B8e<&D{}=tH-K*j;FlG`@SpTw5_|sLY z*v`p5Px7CP48DvIitic-ep0hfU_+M^VCWr}fO_M%pKNRtM2>}bq zE!ZZM%TQ94BzzTuYc=R67Gx)_cB$xm^1@h5hau*P4@te0ZxmL1y!rEu4eZjuj)gj7 zTzuSAO3pAt(l_x4palt((5Ww4c!~yIcSQfinq2JJ26~i9;f!qg13*7t zfXwP3vEmHiFhHJtoBYXOj$4pd zZ!;nkS)0B}ho|r0Yqp#i)C)W*(y@XjA&&;k7!%XrKbrR>e{neKTngvExnN1fhe$HK zUtgUdTb!+|4_B6NRr?3=<6S&!=O&%hdj2CO;tL5MlZU_@OBWig)kMKi7{FJLgq5SN zfpo83hMAbC(s^Db%*oy5IWm_upoa-G+X`t;ZlnWLDE4yd$ZP)xXM?;!~;|vfgW@$0k#3jf+ zItcN2XNVtPTlh*L;SZ^>J*U|C^!^ZcdDo7-SeQb+Bf4eLcoC}unq^k#iM+K^rd*~_ z9ST*YSy69Q`YSI{k@QO*=I4xva9uCz^!AR2=OxY^nL&(fDRD``NOcvaS>f5Zc#Xl3 zjC7zJ%YsOO0%)3$w)w!9D<^WhU0zCLp;3-v-p?phDp!e$P}6OVwnN>YGb4F2lhB?l zpxUMPgiQisFn_C?E=4n>(lB)tO3G?Cnv73=>ff>>mGL1S^2q}@KevFd$s%J$nsIi) zwN3asG?;|yOB zpNa`E^;oNF)ln)O;?+QpjC&>XN)%F?SC_egZca)LQ2EN9t4HwQJsj0A|HIouSLf}j z&{>FzlhNtbn?x80jz)*m_h|DP%UVO07QjG+PEAcKDS)WDg+9%x_sA1T=)szLjb(KI`G-tMq^*-2{!|hO-nf59jxXo=0)YD| zqS1j~`?Q?>CTlWmt}RNLiN6bi93_S%IPykzSE;F8r6T$wn$1U%bQJS(6Sz5;oVQq+!Dui^p~$o$W9p73nsGy~ z6UkxQcvCtx_obm=bW=q;F3(M+%Uvu*;I>=)w(?xhTme-MDdN*vNyuhN5LRBg_qbwA z3rG(i+a5{EOx*KXYR(O3zYe78X8=nfxq`e^m^JkL%zzwBjR}B9I3Z3LhXWP|TWfve z={(2gJ8nPOr+GOg6?TL#m}ZDOBgJb-XWu8!Y2v;_Z4)Upxv3!dHxa_Cs-5b}{g@im-XER1Jh0P*qoU9ZKAy#JfTC*;X$(6mshBJ+ z=wK93$lzuQ~tvk-H zeu5DPY6i*FZNo1~y_k310m-1o{qt@r%6eBRhAY$F z9Ar7)dzlT7&48Sy72L$4JWuS=LfS@)Y*xt_#{@tUf2lAl=8l-_%Q?c!TbA`M_uxXF za$--d(_-EA_`tlL>IIJsts3Y4?@wzrP17Yxh27JedFJV{cwH1RIg0bKf1%WJEozoyM-JU&vzW2OS_@`7XY zJX&%-cV~M?(WoGIlQOL!GC?A_;~)dvufyfN1JnP?LVcFt&0wk;T>-Ir_8_|UUxQ8M z2fqMVq(k;Yeu~zZS6LL|cAAG)wGs_rSZPvwfH%8;wV5+V587@;ALyGgVOF*ngIvd?)?vr|rPvC4co2rceliu*km!WcMI@!V`l z0IuSK$7%LA@6J!5k^7?uXG`cnc}N!A5+J*k0tVOd?Jk-D{$z=oBYjPd@R;@3p0AFG zj@B&;vX^Yv{PyyoEGxc-aA9$9~#(;swzywaY8a#*mDUilT;?5a1QA zwrk(i3vWd6j(u|Ya&@=?+T8l~rsLAimMKt-!A#IX$J6)Kb1QqGsS*KT0E-|ngx$BoN#Dq!CWQ87o7f~33-E#=#5sdmaqcf zVs8ERC952*$Ex8YZaL?unF;r<=9wrV73Ar5CGs$qd2X@T;RaF0wuqa#*%iEN5;Uoa z9qaV?rdbVmR@cuq?Lj912`do6RPA#^@3wHCMGL*tUemipa?ai zA7;!a(W%`9Z6rXWAn7|!&!xT}!Wp|3{Ri=c^IwBGrk+Ve9#bDJ55f|30*y#v=_B8Y zk0B5JblVaQmH9%D3hAiELEd3#{6lqe#<5(WR#wbTnCmtHHm*D6(YlmlrSL?N6DoAj zF0|8L0>SN}ZUH?{mbfbfY^!wf8?xy)|2IcDaDXC8W%zU|TDNZ7w#aqmTS zVHn?3Br2dxlVMjG+gzbvH{^@wYdX$lXz?WdbneQ73!waLCWM!scjh~4h;1^>dYWfT zEvh?_uhi@{oidEtcUdGHo_z#QrYkEEc^F6m=7Dv^jtTP+GTvE7vg1V|5N++W^ACd_ z;o(<@fsR5IDo#VaxWq-z&yW5U-^?J0jfjw9&Ao`m;eCI{81nWo(ExTP6&ig`qeZuS z=Kzj70pQ5zapA@gyjXJ+Xsqhq##B?44eh<63(5R?g63^S+468P5|s?2vGs94un^Q2 zT9~q--+p;`ram`7kVZp<)2|$C!KQ`!ylr5`zA(D#Pgm<;d zy6zm)%OQ#W_u|oJVR`|yi!sBE2y4|aT#Ag>lX9(`plz9gar`uHHHK+NYz}mp$Zvm1 zU^AM@4vRJ?rS<;W=KTY+Alw)1;FjGl*xk3-Rm#4&w_->5yI1!A(J+$o^q(&0M4oVA zLvPlL2N6YL{qs%9G*T$OT}7xz>?TH?5aYdF5az#}QLiyoTJJ5Yf)N#g%{cDB>%>Q) z2KrzgjU~HZl9AuS2<4)KpXv)1Vf6R*EYCPJtu_{p!mtBNfS8f`JipJvNBDo=#(XEi zHZw^67Nw%)t|0I-4q!XGr$^ve>LJ)wRCFBpbfWtNBN>s+;A(}q4veu$`Xz~b)n>B* z42GU;;n&JUTg?4-^UElpP@sDLbgahpy{zZZ!;So`5%1%P1Rv<$h*8gHf&}FQu)JA6kxvAHkY{GpVEf(!oMcA zlcR2lun6n@rlTAf4I0_0@fqrNqqsz|aV!cyofk@Gvb2)(bif~;;Dg}q#x^ExKsGQ^ z$u(!RnP>0pWRF;lLLuAKo9k6b&F^Aq%5*2VSZg}L5h2Lr@Y)v|q;z+>SwhG*Iy_$b z;457TFG&B`MY={_^W{136~`b~){K(go~_Z^Z5hCrTq+Ia>P>bsj~MSYcBy``Mu9o! z7Eh!$R;{vko$o&GA{sXg^E7fVoy|5`>zA-C%Ze*Gxf+Ibrzg-YQ>(;D9d_rYoe3Yik{Fm4zs@{-TxX9x`q!?lHk~?|Li$M>6 zUe7#9Tnb`#&b1Y}6SVqNE7A3vPZj{JFx&j^0!z+edN<$Qz3<_>yq$DaIAH5txEEe(|nQ(C-OCS+r3o;OgCOJ>} zyt)gL^rYNS1m)E0$Wrcw@c=R}@>#|EgIC}OP%LQWBu##I=8k1ALG;LRWt(_=h%ydo zC*zre46#h6uh+9Mx&D-sol3Ug!Yh&VOjP(`_4^Sl`S~sol?^3+Hk#~jm)?8h8MjufwR8QJF6&XL~^-h94eZ>j*W!}$LSqT5M8}3F{dZ`#n3&*5f z$ctN)I$p^^*ucH#_(E;%@LkHEoF!o4$%`u%{cM&mV(QwypXr9hw`l6S!T2_)`<>-jDStjAfaKc;*nw) zvTwXyzZx|Ht)D~SmQ{y@CfPFEgL}Tkv>BIsjIHQ!C}fN4EAM*XL~vpT~SUZ zYKJ~Jgzg*3@B;>hwRu6?F;_-hq=hK=SWn(Qwrn&yKw!QVHM=hOyQ{J>>elta=r zTgkD@pih1Tg0W7zRX_@bUL9f{~wea=YU4Hf>*|T7^X7rb*r@e}9+r zW;4$R`_34mCHfYI!sg;2`hKtM=575NItT5aJIPLlN-|D=ad>TXgFg!$iRoTBNQte#ieei}R`rgf%8NrXq zV2Tmocr6B1tn-w&yfbhRX*bzw&~!B?pBbaVm%m}2!b1zMxQ zoaH)0K1^tl#>~enuS4Qf#xLRcd!ta|}C}CIt%3REBkXxUF6p zB$%Y-g-FHu0S&g1!u-E643%2h14pUm7X7N&+gQbd_;xbaPL53ffCPM%T4mEvE{tm% zSU8#D88^~gJ5r7b|Ce#0S5Bu_tz$HNM{q`K#+76HM}!#v2Rrw%&Eo z)QE^-@0$U!X;v1=Lk~{#|A13w<=OP1P!uqj47o!7kLjfPL!%g>WBez;ZRJGvE5$A* zS|#};$#+ERW?#yL>-SY_pto=K_{AT-cXh$_zD2NH{3O+WxjOnKUVadWdd8O}L;(TF zNR!*K4L1#sQIv8`X_o`KjX}4H-}LjjZcsv(M4=P$W&!Q#qz-kc+{aV}Z(VYnnvRm0 zhq_e1S0wf!j6aF#E1`4;#kP*r3*q)~^@pd=;?hDVV^H&0-8lDY2idxGX8;3_&8Te( zAmSGl+cci3DloCY<3(ExfWV?|5Wh)a2(51RA~e+wmtwkE?yc4;;|wC#RmiCz>uDF_L+Qbu2mdh9Y?n0ZsGD z=hLl5{TKxmSCHnO!~_#7Ju0e4wh@-%e*OK|w}TzTzZ=}4ZGoe;oB2_PGX+6;!=?{= zlI8R?;GOuTL3NHK@^AZjvU^qn>AA}7%LOYa6XZgIgUbS++(i(zYRpM{gJKYFxbNTU zbr4m83u>n0UI4$H3KnX^kEQ_9BbiBAa7y>do+pK9YxV~7gAxZnqS6@ey*JV4H6!q(D95fsN%fQ5E7*DI5$h2`r)Pr_LY zIHd#5(oKNXoSq3(!Z||8FH3d!l#+vwh1%enX12n8W&ICwK4sxQy_tU6ar!?s*{+Ij zTZxd5L38wUZV)^rFhFRQYxLQX8V_c{BZ8K8DRtA&Xuj}7LJI?+o!}?!K1M6@!J62Q`-CD1tMcrI@6{UO=e--hZ@CuUMONMb^2XL znc2&ZGC8eYy-Z4h)Z^Jm>&_cZ88cw})$s0s;uCUDo3A^H1cpH~D7&bcaL%czMD3n* zeh;#g%=`DoyHYqx;K|8KJ3+-dTYhjPwQlPc`UdpOtk)ub0yly|JnbAjP%w54@U@l7 zF}HDb^aKQb+yA`c$&=NN-vve`u_ksG>_6Qdnyl(UiC88`n&@7EK*;X+#GoOJE?5Xx z4q5BxJd_##;eIOUUij(1>PG2@gCJi3lV=7na{oM6`c}K<9ga%5>Df`lfG8yyXQ92GcQisgq ztg>82x$O*OxI;ZmY<>-?F~;mLZ#)i1tl;{k)tvXdDM+HyRzZI!BHSjtMb@odU~*0k z#HreXj_y-@7Py(MGuI@cG9H#2up22pBi9`nE3#LRzWr5!f8#+cK3TJYn3bjCWOSy! zIEbfTQt8$IG^BbwCq!rEd8_P&^ULQ3=rg={@*rw>>(?T2v}DH)@VV~|#iNN(VtGGw zV)oPCd1&DA@>b!0uOdp~gps)3QCAt9(c%Dpsi1^{&6iM0l!CHz>Rp5N^B(z6#JeU( zHAyVXi@kmwh(d)k3nvGs^r(unkG?O(n|LEsK>Net6vOqq2Sx?)J7;500%R-%IksYi za65G<&L4PxJQ2PIJN{C-AO>ZLStD@ehfe;mxA9M$ zH4@CJ_Wj%Lqk7BYNE_|wp0H%qdaO$SJTX?Jpx`d|hq@6&S-hK&`g%cl+(tb>bEySL zdut1GnJ(L-F`U=0I_X5S9~E2BocgrRNIAhbT>;B<89LQg7>abBe9{&! zwloHmYppV<2S~b*B|MXm_o501cNfZza94qzttI2g74(mU3eN7=Zz7x4_^`UXm=XdN z>W$?s4h90Tn@OpPpzo&`QepkC=7&^q+q2_wcEzzZKN7*Ej~IF+0*x@v5K#Zf$o>m$1S7)V_3@%3d#C@>*+mHBOass6NzD|kM2aK z?04Sya{Dyd<~xoKAchsUpVfwDV|x$w3hxrM9Y3FVC9L3mECPc(W9iITj61+PhK8nr zc=x6>R~zEdnV2Uc<;}hEpz_Ta??v{NMVr zogn>;M5g{`krl%cT89Nv31_>ZD@%gX6c~+OL&8>1TIJ%{x;ph9Y z_W8R+RGqdGP+v3V4@=4y*%z%V^R8RCOFF{>F;&2;uJGl2@gEPBCsvoF=1ZF1KXQ+{ zkxue8+i-|R^ElqxE;Npy+#xW{= zWxr?BCXI8qjSHjMl;DMM3+>7(qqujPfxJV=cXP3#2j12`n4O{UgQw=NEOkhK!vIcK zZAZ-th+w`GVPlJQ*mFd_XO=#z(w&$SBX^Q1D=sg^2YEneS>1z8=e<_@m_U4JVQQ-Q z^ZN;*K~I@uts#1aHcYjl%3L;|9$ zK8tQ$*~iukqskE)OrT9dxfN1=n}8_zH+=D!WzacO<^;wR(m?N1M#&iG=Y2=zJ{c^M z9c+&rTFASeQi3rLLa@E_Qy8EbG*Y=iDHDWZKHZW-hGQp~2vI9YfZiT#f2v!cs-R}d zDQqHtH=(AHg&h_`IKy&<;qN71ORRWsjIlnuW%!!Zss~Nb2{g@vETSt>_$2p89m=qt zceX^95iQ_aw4bOf?2VRk^&oE2Lk4SPqV)cI7f=jl4J0UHnmm}AxdEZW!)NyaL_*`# zhTdt`w+jrI?%s=^ndWH*9SM^{7ETcxj`#Xfc^{*@8w`JYjQ}%1%)h2TD0{@AxC*Fa z$gEptD6`WSK>R24wv<}fK;IVvn&4;{n5iXqzMQEC-I<;l$Zpiq@HKq~HWQC1=S`xt ziE~9%0+OGl`|?Xyb>7W~J4U^m$C9EOVnK*8&7$F=d~qAml(Gj3$2&v0XZ}%{IDvQz z^S0GDQ#DRmqy3&aJi|ZN6sx)?n~IBpCSl$UkX6&cR$>)|gRrGksl|1K*2R77X;9Jl zK7?N=q_%NW%#q?^u~m?fuPVLC4Qxgysf+tagbouAk$ol<%zQWW>0RoNLGMqYnan6} zQy91FddKzG|18B$ zBY_NBb&}>;YLXOT^tgY}B4rxx6*w>+P;{ZZ{nl*t@Ru1v@P`-oz`xt&@oOyPW*yp|&X8(3f_ zOX0XaK=R8q8RaH5kKF+#j$L9Q%4t=e!+@97+x64pnWV0WJ?oEa=4rkmS_4|RXj zG&m0I+Mhx97hfJPC2KMs%6FDj^fE!*8b|KLIYftkiFM@;pn;WE%{_iFb5z2>-6$7lVD)_a~JFyH5|GIpPef zRS*A?El9G)djmt>{-V^LhDD8I!TB&d`jfb3Hb&Sxk+1;uM7pc}G?cDoJ-a!CIt40Bj>(j=C+8E@U_uru^mduqi^9vCObXTVw9sqx0{D-fR^-7iZbyz~URWv+wicb$5Mo>l%-=Od*I=RF$*0^EyMiDfhICvj>GX&)O zY}ND1mCZHT0xxMr^cW}UbPjvyFTp`n#0fGQKeBR&0Qj_!@gvx9G#3)G>gSSUPB9V| z?<8)0hs8OH$)DBRS{&aNxGvXs_{mIs25RJ32n*3VOLbBJyNLCv%8#{DT3YOW&xjY9 z&J=Q?x}bR>og?4HcCI5F-PR6Wzii)@@}{?3pcrZYP0YqkN@YlthPTxWIkmc=-Q-qE zJ7!P@8zxW}N4T*#)EuGu%kL=2&dghCWMzt40m@O$il-R@!6`a%(mqSas`@n9Fnt6Bj?uo1D8z;j&Jl;x0`_;$l>eIno|BM5~?q9+}*p4tEp+XytnVLAFC1s0Vrh zRlphh`Bkrx)Y4-&N8oDpGYPGB>Y%HfTKK8!v6KIB9j!s-l=MfY9!O)`97so;1!gpB zyIbHNtYr4A!5(&hIf}{2$qSK2^P-wNWnB}?4A#8dQA`w0BF;e?d^z;7{lOWR~p&)FCd15-H#Mm($*EuF_pmceRR}x+MD{D^(@?^Dnk#7+5(T#m|75ifE z*Jll3cD}`#3*R#{cv)J1TYi*gXQxk0Ps5j;Fn#NTb-E))KY7unsq&RAXEz_) zMimIkr%czr$e}HqqKC69_jAZUQEMa-_6+WDj4!-;|2~Ju2QKt17#{wxA7-V|(VjyD ze`$6+JknBq{x5T}6s)>eX<*55xE$;FV}R?oZsLFxIuiv?(d`Piu{75BwP7lGqzni% zVD3&QTtuik8%!wGmC}Ing4Pok8vMtV{dLiR-lZ^&%QI|}l`N3wCX4fm+zjdbu=%X! zqw+u^b=0-u{ML($mEVa<&&bV#5E$2E(ew6=e(blSMi(UgYvkmVaPSpF>e*(+7j%JX zFo{=x7*v^Mkgl5&8Y6#2b!QM;z6EntGZ&q31SQ-}(Ci}VTA!{vs^viQ7yL!5B z=oZg`u-f0*Zb2a=mgT$nt2s)ELV)IvDDZ&(5q;_W={FWTR7SGD@z^-mNFiAF{|K^Z zi@{%rFnljR0X%jbrG6Y@KBgFFz)}!yh>SOFY_b&`p)t7}Ek09sZT34u5l`kb^EYzG zH{sg{lHRGED&3&V8x0vrVXZxNIno~B*{TaY#SYhU3mLRorz;soV4aAe5;cpVuKc1Y zUQT?eNGRSo1I`t zJ)dJ~OYM3r;j|}qW!A)}4@bWZwpNFur}ja_WGeiKn>E6MPJ*OQ3c=&i4|r9BmlQF$jtVCPIeKm!9Kw5 zECh233?;x;&oo3I&6X+WpyS@;=1r*B*R7%9^ijy zgq!R0*Xez&C{$R~Zc@JNR!a;rsg)14H^ttyfWAT}DR){r00Ixyy2=6XRyxjqd_M8| z+mj+EEu$2Z(Zj!f@&6o(H&9`)Nur5+{^=c0q$ttU2Ozicl z@vDT-&JTUernYN?vZ4TfGqlQ;A+Hoax$vI)PL9DThZL8)}Z85Z5<-~9n4 zN(fTyUf?3;xc??r%=XltCT({;h)pFVbiJfbqL~KxA|V%F5x~gRb15aG*yLQZ^S|#9 zc;#0=ec1&=xJAv$#PLw-SF`mnWo_i>MS z&E7uJZPX5*YVvlzs~SGj0afbrODL+T$fdDrd+k294IKeKBX`qq7sc2oK!W>%{mn~C zMHnEa(HT^`fFhdbkbo3tVEF+cPa+<-T+V6k)T}8pI^nL^q&@sGVO(|xvz*?lpwzVUH z{$!5;&H^Gw{LBAEsjvNqh$~qHN&z6%!32$S?NBu1vpWc;P&xF!&g<0gNb{Fv&{vL; zw-6Md%T`2}zPm2*2(*)VG-^Cq_p z>xBT{zUVxIMZA4qmX@r1Da4xaMr$6)T=a?e+(vnlE>dY3IQES^5+>XT-sr+ZU zYXgf6aCnlbt%fC(vCz5%e?=>gH&DSpCw4D9>R-^xFZg70l_t+PQ>+X0+ZsvDy(Sz* z(aUV8o6P8o6S+_;*5gF$26pm~2kf9rI3{3GHe_hrNH+=B5oVb@Se9|pP}70?dv1+_ z0ZyO=(A}J_B=!{K1Z+E{?pGXLoPPw=U(iDH0yHVd>Pe)o-uq$IsE)o_IJkEk!)ADG1q`q)RrWV0*{p(4~T#^R-IF-B70arux#Ra~l zLVM^@wB)316)$&tM&ap!kcy^ZvP^}!c`IwE??_1pd75cP_$p=b-YW_P; zp5-IlrE5%MK+FyrOmU+8sC-O>ybduXZoSWUgGvnEARyS?9<})z{M}JG{yz?8xmVd5 zKHBsn55u{tU7}Q1!D6ASI%domraBE|E#-2Zh6%pD^Ak_S*GkAoUj1$Xl z=Nb64B7$)pmKNR^+1v!XBg?uf<@M5DI)M%Q_dhZzJkgCY63WjA*vPur!>fK5!^UiY zpp>%G%$A~0_U018dsFXDDU$|);9c-8&N)^Eb9mb+{W+2}lz7@*y9;V2I&YH7pqHbU zb_>h&>Lmnv6$3q`=DJ#Iq|;APWE8r@dg(XmP~V>D)I+vSUP%EL?B-V-Yi`u$45Ayj zOZc=F#P}Q~H^9^wuGX7$C>)TLT+ANv zkzz#c|2=^8#N*gv+{==_vSke9Q&cCoe@-Zi@2nlyN|(+j9#;Z!E?RR?!gcM~70f#G zfL7{zu35Otov(L8fk=BE=%Do%?z3&^zifRj32n=sa|P8hW3(gQo)i9B1EwV?ZJG=` zS`&3^=jvu)hAA>vTVC1drhGLcN%r9=CN%9E$ty&t%;dRtZ&41}$n5N#9RuQYpFnb~ z8S}703-=FawK-L#RoyH*BHH)+>$O>9E0*fy7v-+!>SUw>jG2jG$$`PoIjh7keFv#d zE~1uTnGaAqx^ju3fr7#Q+~(rD+_YER_TDN$tKWoN3kawY- zCfn*wyicuOd@%4!`R~k#$16cgyd+LOaH@pUV4X;^?94oj$EZUb2t*)NjAUUnFBd5% z1p)x0BF5y;`w2G2ayaN|zKgh9r!@fva;DPTFu7*)2CnrFl!LwAG&446KmR$4L#O%Y zFetd_a;O78mZ+JM(5VDu+JMyeV%OZ`w$-EpR~UsVa(dHMDDEn2>Ws#gb0P zVGoYWcoqdo!@N~~VTB)OJS|4jC|D)Eaxl67EmJ!pww-_GAMVx-7}O`oJ84Cua2=%j-TWoZ1%GjNT>Yw za=jRd?11DZW;t09%*6c+uSKDL?MJd-eNJr?AbYpg>V){q4L36>p zng!&dnq|Y&3KsrB(WEBy;kH=2je)`PSqj;a z>#?4bAEp`CC|^xR7#3Kax?nUJ2efjfSY!BrLh6mJJ!jXYg)Iz{K!&@SB{d9FviCS zeGWvVyL}S1|L`qLXMyx>wwS}g8Y?c}sxLq%;rrGS^tZV8@=|B1H(MPAXf!7iGYBZ0r2HBFg zjU+JdVwVvqn^7bwU-?z5bX=m9s-(>V&z$f^q(mtNQtmknc_Qhxl>^X4P!W8*CfP## za%7#U1xA#3+hb_ZDh{<8T?8wHJYzRbCgR?cC8-o3Q2-$fUOCoYamCXAfJ`ROre7?2 zU{sTOQEKP`mf*sG;qL0^gLG+@WZ)53Wv=lGNlBwzcn|ll{j|kz9U_>g%gENEtwm6` z)cUjvP}|hL1Ce(ycExePz7;{Oa-l6I3y`nN;!)ru6gR3>XHnR}#Ddf``m=wIK|hiH zt-JD9WHFvhqZ6V52tpvvYv!>7UR}{C@40a^Eq8EG9!`hblYXdWgyT6QEWB#9zqLo~ z^J5U)4B-Bt`t_zV0Cgm$>dne|qlqubnA-KR?E`v;a?v{et3px{=KA z(B%&r_V5~5pB>Hi8;P`O^R4(%B4Qoe0zXu5XNlng0~S`?S$&Mj>3_yTb#@^*G~z4v z%{>2YIA(d{@8ocL4-FS7^+h6qtBpI|C=qH?HI%wlKa8&kSit4a0f_X;w z5Ui2LU{KFr8;BM!!aF{n%a7{STCl*%ub2_1uoOzor~y?6HIWA8yhtf{yH);()OYXs zf(V@&1?J8Vk}mcXs{fcYlTCsQ?7>|33Z}SMlFL=Ko}IqhoE&skc8KXEr8!Hgj!(rn zQx;nee!%-)&IUKr55>uL2w;gp>f7X&Hz8_tYG5uPM6g>S3#y=9--GiZEA<{{8bCn* zvi6rAPbY-|ep^<`4m=bDo)!}RKAX_}_FkM@1Uo1Scw!T14$}H<6U%#~HKD^4XQ2F)F+1`JEXHDQ$3+^(F>D-2}KOf$qHPpEA z9f0CkpsOcT&wAEIx679#nVx*YI?#6gc;if%zF0{V`XYboTHS|dXp?%tk&6Ccif%{| zTQ2UQAG3o-r3ve=G)AYpX6h$GOXf$yewgH#}D3 z?bOP{jqdGb#7$b0H!f>5&P!dC=-#t@LUoP$al_}BTzEr4zGcvA6m2)$@^Wbu@) z`vAMJM{b3M&4E}M*Km^G4Yt=>bd%v|n*_m~fpWl;R&|wkN)ItD$Q{0gOJC5kyi@N( zJ^}Dc9m-@ybo$H>6SxdwU_QFWjBIt_?dfK3D=dgwoX2cE^=(8GLnhG#m~!EEwXb~l zmqnEnra_VNawJ)ND?9Dh!$_fJNWTpij?#-O8~u3{5#%#7w89w61}si|=46vys#UN?{LIlXndOtMj#DZ$jK=-t;u;|~HD-YkCHH=qP2;%hI;;CEvt z?3sx-t~RVW6RppLOu_e0I#$@~KpoEd(I67+5vLQ^XsIm>YdVMfO&qMHW$u5Gldway zmxSQ@Yd{bOSwQd5qZgTJBI7p=gi#=TqH!~;^{qjlqXNYzT#&{pUlr|$1jnAF(Tx~P zgpLGjqa(PV=~$@u+6>@?#u`#$Fl~qVzWpBA6@-?KCBBr#wQ=-f+wN%>jSmp z7Chuj34gRh_NbO>7UpDe8w{8_W_2F$!2Aai?Q_2nNaJ~|;~jyzP+R};`cE1bX@tCE z%B>WRxmUC(-;Z5jE;P_>vW_edj!p1mc}peOj|tY2p|KSa1|p9M622uv!7ZJ+yj-T+ z`FCVyKOqgMm*RmkOj)fu>tn&qYJtsU#7G%$E{uH=G%ZQ(wsA>@@bO$9^8l+jV>BAW z-Y?}1YEW-3V1-SUxD%;Q;Q659Y66$h4U;1dBo~o7qG3AtI<~cMP{8UzG^VW5B*V>c z^be1CCsxv6Qd+tm(~nC_b1*xn@1b(12S(_3jM9|#UE;G4;53Q)W ztGXwFfVGyPik5A>>X7j`P`mD=A58f$+}z{St}iQVM?}8F|1H-%vj1lf-`1}Ye$2bL z)a+(Bul}|}3cNlx0JA0t9<-qc#jGZ=7veCF=}B(<(WuQHGO%Ad9+HNmCo40zj*HbZ z+k@|ovVMfo;ryv+-XM))mB;P~(6!R4*n}axau;4*xPsMh87c!4AY%5JGYl{y*okLs zQfMFl(#nk7`2E!5p6*vhOPNAL-g+j`Art1pW`4a4cgnu^7!k;qn2LVNZaT<2p1eyx zPjM|&M)RYvgfC%su;L_L^L3GuiK}6yMAhQ=ex0+J@v^ECWpCfik>>5Vc76%+5^rbY zss4nYDunYBDE~5o=S*K4oe-+ zJtIb8W-}QFCA#_fcC{{MmxE`)<*Cs`*c2%1f^5~C-5yLo^gX^&LgHVR-Id&p)Hx1< z7EQ2Ro0LB2E(?W951_9kb3nGA*BA$@*OGHDih=5ZigS>lq;}U#c^?MeBPSp9yT<;( zu|0SW&3AIG+Bk@~N;IBAQ#?=%f%(3v$2C16nyV(tY4kd^#-}UnbU4BjJhbjvmTm7% zwM;~^PfR`fj$7qXCkS$6HCouNq12Bvn=}=zx&EJeL{|Rl(!1l6b!H$}2_-LKPL9%k zgc8mBvmbY9Fpj8|c{KM~V{<__y%PCb$#VHs)_|n_1LJ6zk88>mqBRl)&P(k#yCc4p z^@Z7#SAvtW%)s}sGjHyjhhUTwm`l-XlkSw2%N0_w8~Z6#^2eH#SYGBc;o|RfvhC@0 zHvzU9$Sx{(t*WGt=WA!h=0TeZAEtLlSKlgkxFEO=se~TS<(I38R6D*IB3AZH6X*F1 zvAgS`Sq)0o6Y*oM?93NRXX(fjT@>}wouZd@L1fxTb)j_UW89RL>BygXs7XjU0s@W;y#6&2SJB=qng4{n9Rx zI0-*KfjYhW?_7*dUO1cvXsgTG;x=&X%~;}SvB}B^%)ue+JR!yVT%Q!gq4a9(8kG^3 zjlv&mEh#W^$fuH$KE?A5lSpoC4~P7c^XNII#WR&TU^U*;#J{*VR-}aaOVi zEXmUu<8QkQ$Jd2r29y#BAwrfK`N1QJ)kqDvaN!Eo(IYTCPj)1y+~YvYN44a*^2oTJ z?!(WSjE6=MlLB(b=LnX zz5a`P{LQT~1gDerN0IeMLO38_|Arws79+UK{=VpUJ;Um859m@(eY#O zshig2Qn}!2#4X40=nu-!JoTDSIw!7B^1HRkac!BY8$*erTDrC}hwyE3fnAb*ZQok)G*SKqadduF zU)f?+9j8kDz_v{O0wQA*(CR2Z-reMy-lzkJzN6aXg9Cn$`ffuYXj3Y6+!v)eypR;O zaawDXo)@e|&5x>3vTm+-faLF#oOumf=714Ms+~YR-1jGFY+^DmzcFK7?EC} z3$tF1xQ*MQtr?KU(%_V>M~xp9RWeurO)jABfI~Pv`tTx~2V?>T;fDn^uer%J@}x zYxkmzPycUf3nF&owQfN7vt4rdQ6;aA-MZw8MtC#B8bVPd{e=-xdF;k@(cJo}GfAt>%$l?@k;rDBF;brdzB>uzRqy!Xyld-R+}N=Y;A1h%o&FUf-k zT800xEf_&@7w-`II?JgAei7**AN3YP}uPRNT1&@UZ0DQFmXJbmw& z6&L(`amZD7+xT=%Z2$j{=&d2Q(*W$nP}ix?HDFq2-3PY)`AN5&jMdjEv6}+Yf>h?s zEkQOU3l`d#7ykFac{>{9$&JA(*_T}lCA;)^aRdxo=iua+ndFx)^|4=h-_r`Ehk!lv zBoO#aNZwx@Wugo>BwvjEOipDzKiEOG@ogb1hSzswQ$kkYrSY3^U)_}x0iU2f#{^TG zd8$T+Bs0^}1E4r_zRL$7S>1-JIG=}TKUrj3>9t32GCBjQMWnmwHI2bzjNO}JEha^p zGi|n3o=5!jy+vdhO4<##oVG0a^JCSCD z9wSURd!R-QVt#S(?(l%RK0^&{G{UX40K-DM&Es*0N^e% z(nz^G2r>kpHIyrhHEQSU4B`i=WbLx@4GDX{Io3pSlV>QUS;co*ze&w-Bn@;#mKEA~ zZGcKc^kcPg)*yq)2wbYc%AY_r=-)dtmYe#O=hN#Pk+884JgBL>bnx`sMhZs(u{n5x zFfEorDP&%SV$m0*jTYcEW6cwzs!c;Dvct&SHLXHzeJ=z`cQk9AccLz68XM|KehWu@L6B?41qb<&54S#~O}lA5XOraH_H-@MC&%lC^Oo=>TNmWAkjAwhl}3 zgS4A(ayAOS05{e?6oli3#tq$l=$NPxhOS~K$4+RNpd0nDGA`5n z8heCzY82*>XrR=ltd&ZDT%wwvQ_0|+q*;d%FNy57_qsWri1gfwG&e}Bx~?Tyhk zYPPXC4OEA9!qWczu|CT-YtojFiR-!d{ES6YEM$775~$1um0^_UYE#OpuDFldR-3iH z6v9P(8<3t&8@Dd%K4{C3B2!=d>8i-uVVyQ$L^>;WIC*iRqIe#U3MiS*XW~BmBycXW zp)RDXd@k6>5k9UCjpLi6+x_oD8tFz=?S*>d;pnLPXEEGzvn~FAa9IoC2AhCm8MibA z@Pz2_S^Jlk=N4+c8oXg|s}_LV1&Gok@Gmex{P$pIPmhySp8& zjwaw!Ek`mEgTm~S7UQ@rWb7;G-{gsVmL20l?Wok$6=4a$x#{m1t8la@GulvH-N5@| zG(WK6rgdRmhp$|@O?rM?Zz=}WS%w3C-kL{q^P*02^U2N=u<&?WpM4qJs*C@OG`6OtbGTG2LH2Gur*O`jCxY#^f@nJ%@}EoLxz?_=@*xR3Iv%6wiDqG(r!F}@ zBgpCQ{l@5jaYP#K$6}<>P_2Nv4H`Y`{iGl9yUGbyaU3xxRGdYy^3ioEq<)PB^2Bju zOYdO!cgjG$M#NY&7I+XF1gb3440sGPcQx6Su>%*`UP|6rzT=&DIOq~wYj>tip>v$X z(t2=8&aiko%gl6zwa$qwzv#DnMyJ)pj_Li62E?_IueNr@#{KK~-q|(SNQZvgZ5}3_ z-nva}(kF(Zh-CARZ9TmK#{J%Ta;>%@QRTUP_Xc^_$O=xQBly;$=DnB zco~k5nht zPtf?y{*3Ko6n18S(t>Q5Y3J=CAeWHaETBWNm_=4^1iB9;Cq6PVU{h$_cn1x)*2UNjVB-E=TZv5=z&|0s63o+lPJh6XOc3uR6Y6$IuZQp&$Gv-l8RXH3xZJ+{c zNQqCoxi37rvdw2ds$c2#eU}dMK=6dRR-~#ToS39&YSetO;Q-gTR=PcG1Q8_3mJQdR z?_cLo^~I?_tS2@$JQu<&kK97)WsUpL=gxYVYE>7u>N?$u+z2cH6d~K!ZQegi z2=@@4*saBqZvOb3{Naxr^R*zYzpb;ky>U2j6*)U%V7s6?64M_g(k@EI$n83!By}9JVml*XQfHJMTgmQ zF6Ei56b@TLh+soF_b#Hy)49p6j`Hym59noNjc=4^sRT@#(80KsRnhuLp`a*?2dw?^ zZ9I*&rGjVj{B2LQPyt-qL)4Peel8(sYM@IKs!mO)8AdRMxee;XxSWDFpjEjKqx!O#_+?q~4Ej=0G&*ZYk6=;J=dohKR0{J$@R zt(OKc(46-2R$^=?(sV+mkej*CNu5)Fo+2TlC{C$stn04{zD&^>KE*qf#*OpnxKDy?(f)ZV%mn;@k6co zbSeuV8s&qvIx9HzlRlppb%9YIfzqmx=nT$U`o$ldTMYKfKGOW?ezxeUyn7NMb{n{Z zp%zh@AhX6rh@nIu@4Hbc%-;gL>s;~YRF4~H80b(_{48sJ;MdvJ4w&r$tmhy}Fe<9m zCcv#YOeLI>Jm7o5Two-a`3mdD*#y&p=TjLR)NskMsh_!92A6aXHuC__b0SmD4ZAg4 zOvYWp=auI&^^#sv31l~o0%iavuE)4U1W!~60gjp2Ua$L}I4?^9U|aD}qC6%PQ1 zs{Eap_at&46>))zCCr_NM=Ispi#%F=!<(l%2sP*z6bz=xE{#u+AoBTj1s3I{c~X;K zWev_WoiIyqI4td-L#<#O89|MgeiEj%Rvr}9l2LL4s`*oXL!oM)JWN|P#nZihYfUEB zu~)|%Wjj9{BY=istCLv$X)E%@edLMnU!>hdY39wx)zU`SJ@1^)*qG* zW~qj3Z=HRmHfIYmXL8HfVbe=#U+Ge_otbSEUHi1^w)4 z1>{In^!_2t;dUh(&u8eY@WHsMGyP&XO7?9qBtpDl2KHDz(ThoPmj9I_=VRnTp2aPE zh|V3nc~WP#K!;qDBHT5~gD)5fTK~YZ;^5|9#apum_@*%~QA(F)H@5=;LWP2$!ck&` zXq^K-3yHm4{YauxLGIrAb|xUmP}6$34o%u5bX9Z}sLN>Jg1d%v8XT(y#i!8JwbPDI zx^r=Y7$*Kp%B>X=RC1fTSUUOBV+buun^a)KEmagbuaoN7({BU5Bn9sq&TBw5=?YS? zlvc!c1&`SzM;A^3S}5H2nrg`Ble5a`jFx3*K%KWu9r+Vd|K?YB&eGV?+Ha3`j>6t) zIF^9XpzL`4!i1~9_{OKsrJ_rq{}8 z0#*?XuiRl3Xj>1AT*O|sdo|BV%l`^p@y@)+QMcTwX^Y)@VmqDDM%?_CVpHK2a;Lk} zJZbmOC!J(7p)I$7;|YKn+6%&3%Tj5hVhYKpid=R$S>&p1cBJ{^QlQ_7A|LGiNPhCQ zjJ>&p<6*2hDPfMAL};C~?OP1t;bw(s5v+Rndgz_~KPEop92koLp~{fhl+Zvf?EYuM zqPDs_<6VmIF+c~tuu<^0d5X10xe?<#@~B1c-;wK^c$)B~H<#H@+|Oj!9+SU*K-C=! zkb5km0PMgVL``pHZojqL-C=wyWx7_C0sse1w4;asS(=q_ARPdH#?#ofFr!w1BGHnw z{D&>)kY&&w-2WRp4Z68!$zt;`j4fT+eXLV<0nu`0ll$%1Hb{b)hp>l5N^3@f1C%bl zSea#+cM36TYum3k`mKAeJFsww8JS2?Xc;K;f4Q9!VTiZ=#`jVPd|u0QL@8>>kbOAp zZX_3Wc5GTcMtGpK)f<(cpm=(Qk@+@NkiAY5Z4prdthqppyMx>i zqKz?%?a1;po%McNEQnFEAAw!Ppx780DXjp^!vzQAfYfT5>3;7$?sYT(N279f_(H6Vgf5UAV8BVt{m;! zzc4H;UUuq?$B1Fu(azsjqJD8J7gbN>2Ai=F4rRbudUuO0vQPfbu+#`1w>fUAn1Gd< zLZ;Sw)s!(`CkVb zY!pQGpjgmoxh~Ug_RSVq+aK4`!g@bmb~VeY>IttmJ;BIMa>yYP*hF3>&0dKqhNtaj z-fC`|y+ZQ4)aPwJ5JDmM>~QkCAOG{IJ7rMDaNtUw6FX+BU$>$JBEB|`)eT0Bh~l15 zLL*bN5;KetB9)kg6}$n~3vzjg*td#1IpNw6S#jMo*k*6TO2NUN>Jc{gZ1tIMrmD%A zS!=j}E!Tv@^zlD_%p`SlUV}tDYiWu&m?4Iznml?^xa-J50Z76-RJB_Qlrgjt81{4C z88oKDt`}N=-EI=pXb0Q3FN5`WbV#QNCL3Oj_r+9v+csA9gaT^SrZU{)M7)^#147;{ zGLWxz$`m*7ivOD;;hzHERSfm%J_~-8k4xfbF<3g5CZ|bskHBqF_L(iCrBfwoV@m%) zWos2p6@kDhiPnUv*N=SZnTuPjVuv#@0ph}Ar@D-$ndUK~lbsyvfX}oI!qgw2>};QJ zY(jb{i3JYDtMxSs898wvs)P)sRVBK29J*+MbUNbiS^E0=R;(SmSy46*jjdH$+rBGs zu8C8e&j+|RBew#D!)|XWq;3lCn@I0S6T?Tt&Z4|~j58#&%rp)0h0V?^pybOlDd^sPf~dF_-tj4r0YoY15bm*t=KcMB0i9w zM<&E+>raYmR!KMocKlN+(<(O;Hk)FH#F&b&W)+rqnc5bGy4ogrKkK^Fr44%={$iNh zm&fEQ*Gp!_NGLpVVXwSu_rOH(9w)xp_R_Jauo48P*T?IO>jH6J+oYt7F2u^nSZSs9 zx$-JsFDH9IsV54&1oquMr*+^KK4$ynQ;ny*lY|qDcVKr8*)to@d2A5TB?kGpy^B-N z$VgF zv0|^nm#w3*>_9HFSTzNp+KBQ+nC-LlL7KTAFfuDX4w8LgI{K8sp8ryhhZvjyHkXmM z)5kD8hdGZU;J*}*z5GHeb`0^7_%W4?ag{V@Q@;2A)c3d$)?C4oYwuBx ztT)ql1sgfln|>b$Ji`OeBq?7Z3@}uJ z6XXkbBrxvC$p28V&buYj82GA>Kda<~bIy4c+!p?N6mq?<&mUxE+H1%GEoT~s&`qWr zJX7M>L75i6ZCh;U4x~LXy7hfz0JyEYL@CEue?x*&mXAqxRTb=&ZpjCEX}JxN3IXxr zWOBt>JG1K;EE7JWh2$8OjIk#4_cR5~ESKUJUTDUV^0`hFFu4r+px!Oi4@a+U6;Ve& zdZ)pvguXaiRF>-*@te_QPf*}!(qY_z)ct+Hk$%b>o~0s~%=-O>65t7$!=2^UcMoGw z#z9_Nzd)HQAg5blgYUZ9c_ca&g02CUgH^B`LbV|BHFlGVd6VP;G6^7OO?d1OcQS@W z9>(efY;>}W>&lCW^Hk5qM z!r!!vBSA~>9{*^-TMDv~c3ZZek?f=}7z=8_t(7V_Ma1gt^ZJOwU7qqpdq_9LRXEaF zlPJiC!Vwvjqv7>Q8ST~Ei!fWw`&20U%Sf6YF5ekz(Ya=X6_1j9-nSvkV%%&!+m~z4 z|HW@Lg9@}WQosQ9RG#-c?j?0HBNp`*W|dUl=uyV%pg%{5=L|X88w>mYoeAuHUPTLm zVPzg{a|>1T0a+vfpxLJ;Li0RL25hIfo?y)+Sd!^N(kORCRH`n-#i7!V5BQ3yyKsr?SeC*Z#ggg)gQfRheVIv#zLwyL z4fF%4A$W_A+V`)dOU=mev`eObK6JTFawTK1NoT* zaOs$=H9GBSAeW(y)5Nw;WT*IlBp)O=+MW!olv6MqW7-y#J&_XfY6n*iH3!>cmn3h- z7bCt%84L5?wx~s_-xX2%iO`(drWk|VFR^M58A_~Oj-eBw|MLtIrFX>oCIC}FtiSVf z>1s~z@{A3_vReeJwvhML*_>M(Q`s}}ppJC3DyAwg#WUxTqJq`&-GKXvEyZw!NUSzf z_kWGDIN2dv8k(;FKZj zMFuNc9rD-(>iT=h1UjYI1sDu7dv&aUw^(eQ_h;f?ZW4jCct<(={dQA)p ztRKw+1X3G08rwH@!;YT8lRXLXQnE1E)U7#`?!=%3lVnx^4ekiBIdQqZ@|wT(WY|ML z%m6gzg{U~jq%Hh~?eW*u<~E5dK%0U=u+n%(e7&U?@_C3QCev?<+zfZ4GP$%MDuF4F zQESOX5b?zBp`lxEIlZoNkzJ)jz&5H)RTD^mt_WxlSVEkolesY>oOFDHxq zg^pL;jdF-?uKa2o&7w6*l4m0iv8h#)GUAg7fE{3`yAcv*KgUFrW^7o;7F7PM5+H`i zaR%?*H#LXHw|vtFRgXZ+qwDq`kg#+Sp7|(d!wlq`ius8PNat%ju^VJ>ss@3VmqDq%&)2MW;Mn1ALLlYJ zOZJ!F4Gm(Z`X>FmfUDOdsKt;sMHt8X?lPZ?rBH58(K%6HsPwJ_vC*b-pRXo=fA%&n zZ6!<%689LqC4C2`z1i~VK3yTx*amC(d;c`_!?W$q z)Gzr^84JX2pykJ=Zl3G2h29}DojLr*yqNjRr{Z{z7;T?zCv%9V;mPNLa7qPEYfHdG zcgfm#VOD-R3WDzFx#^BKfqp5i;E2X%%2E_pk@rnz-TE-hG4%b-SC7E!7t&h+fg2EN zo)=vhH@7*n+LUaxLUl~ZjgJb{7FZZDI3TSr8*KVl-9mp;OdZ&4yM!sqv*WA#aUjd6 zAmtHY6vK8`!LxT-WJ>%6nOKrU!tfMb&I|;s^*%(KOb8se0k+z)&I^rt?AraHruOX9 z1;{gr!Q%T8Z>Ebg%6k8{V60YBEgu!uVo!GP>Fji-e$||aJcGnFLg`7?IB=2qOU)2> z&8pJJG94EQIGO^Y(HjvQfe4lOZL}o5jWb4jK_2uc&vo79d$t)QBEv@AQ~THq7b5O# z*pbXLJg`cDn>eFYxG3X;dL4Q0eoaY=LR&L-Yd>lp8)iSNX5*d2+0ni0AF2;>)g`z+ zakUe~X{CXkvWt{eW#nPyjwFn$0?v<59X8+Pi;qq1uN`Mab!v>?+RCJqm3U@b=HC4= zyTV((4Z%F$!Z~nP<_NqEQ9|kp5&>~^$wHkvDrpXHt!9kxMJ<4$JGrOqYgexxI$i^X z#B7D(0w{HV?oE*#>|HV?=R}oB>+aqaG1#hxb_nI&H}R^>ICF6WoAc`gJW+wB+sDpi zse_+<gOu5amUtJCVXd3klp8+G2a zYQ#hEJak&ES*uNbrjln0a3r}+H3^1*;5%nHU3StfqONq`IPEy)A)IrSgR&^Di7EwA zPBYjZTbu|8S9_S%2Af7rYFksL$s7|>ok7#JG?`gg@9J&7NFJj!vp8?Pk1m1AKbM@vS*h#t zVg@IiXy0WPI~m(%8|5`Rq-jD4#$a9C`VNIiAOAXvM4Xm|k~?ic%|JhXyD=*n*00e| zGLiLl{}Me*Yue@tO?ZX*+J;PEwZY*)V?y*(Gv&Vu#NZ>H9T_MQ6_WWU_^g|GTAlGk zp$sT!uNw&}35NW&LnXdn{KTFRki^Tq+IUQ)4UoRYHX3`o68cf@ysPX%O+p%m=w^!H#GUiVxo zPm2{1Ju0--@`W0lZdfEwO&~IIrDRD?C2zJWvo{%q6xGw}}I}6n z2*F&>pny<}D)ghUIEpX9fkuwTI8PJtWD*-Lr=l;EV(m_xjX+km9WX4V#$<>0U!{R6 zaW#hvhe5cRMbWJOwdy>!g~hgaEgZ$dz0w2V>C?8&jcZBiwdkWZU?h@6Zb$HsfSRe_ zW8%B5N%u24eXH-mJYQ};+uI@)!pvhi6XdYX?a6&h_iWi>pj*LV+k|R;@2$62RsG=uxoConXdyg_kIXY3`7ZWH zkKO3yI{kV-)EL&dG|k|q%3J)jKaBj1p3Xw##{ijU60(A@xrz*Xfq-E^Np6YDl+O$? z$#&noFhpsaJ2=P>RR7urn>X@LOj^3~u?PLAbr89YQc6?hohcuS?{oimpK%KcGG={4Iv@ZihefCjV4&h;x zE$gUU-(-qE;sXR`A-_C|=E^Ih1jM3+bg_ulOML5X?u+_1$~^5C;Q?S}i%Y3#`$j{J zUs&Y{{;bVHg#vDpM7aIVUPW00#9y!1nPwn%A%PXpF)^81yz$*>=kSY@Jo6dj8)ng= zsvby)2pvpv-l^N<87Xc1B6$wX#+BqD{= z{f+%R$#%_%2G@!c*$Yokp{63Fyi`%_XWmfeYv{!IYF+AI8-Y%X$-@~5p^%~aM%UH7 zXGfA=or}TCmryvzwc#+6$-PLHKT^D$E3~!3v#DoUHRkVoY1azk7?FrSTo+$;&3&p1>ERTIbvRM;+wd^8e7%f&G8aS!vpn~+m3Fitn0l#D&1Mf zP1u&2!})-<&Ei;3;~01MZRrCLdsY*ZFb<9=H(t+u(MxRk*xVAhK?vOY1<|Iujef^* z$owJJZu^R{!CB&Iqcx42sJmk~=WUKlh_l*v6`>S(q66hVmG3GEZZXLTptS9^)T=8( zEt414`=`vG=b~<8rEX=nv|_*8lhFu4onck@9~1xwuML0k~Hxbvt)pJ|Npnt;M#W@^?mvC6?dgapd`RKmfYpVkn z5nA^V55x=Rc~D)@Ms7qQ5?Fw%D~AEzHH1z1z2{4tf@R&+xecT%5v~-Dv!|g7%uhH1 z1u)=^2?)2bOCf90tSD{pYU^wF4h8|E`MtwP?9g@M;s;U%EG0D8gCVL-Mun9^#>V!a z^FYp(1{bPxICA|OKGtxQ$h_w%MJKFr!bgcQ_W{6T#8H;_>Qv^ie}f@S6`NXmx)wW` zJhte6(bjX?2LI@PE;dfgJvJXFkCNaHKqS&k+FXeli$crIB4{tPAt+gPD?(fVlq*U0 z{N+T16etzgw6;w32W$_IB}g>NcTAp7Punjny85Y;O(M6_Lr=}7XgI4%%u zu3ZiQYTE|@08)&eTC@j*^_1_4$mR6(iV*2DdHy!#ej+8bTgZRnS+r)m$3q#z6&|Pb zpu@-^THWlrr6kbjgvUFIRz<|GhI3o$NykKimQsiNg69lqeoydY=Gs6D1yxse5rId! zYq3N}tD??Q@;pL?j70*_&1MU{aUdQZH$hv^Z&?g zVWA8EhNrM4t3h@d5Ds5nMG$wgm7wgbqh%RpJR_z;YzgmXN}ORQ&;qA@p8Ev_N}JYm z635#}$!JYdNu?uaZ%8n9Ohm%E>_bEy&8*fYpu*mCarS`K(dw0y?t>ea0pixdOIS1xJ}aCwFeW|g(C4CUJ-6Xe zNM8F$)RqC3b5XYp@h~n==1u`JVT&@^c@8CL@Pk+>KKO3Q?-X>}Gq5hre+e2fo6FUbcV~w-bY(lL7qWv0t?9m27YLDkJE=gas3vjrE|F0q=&_pfAK<*Va8Kj&q zmFLf&A{aK8Aag`Y_v$)%$%Y`uz6f>X116DUT=!NThV}WLw21tYxx(MFe zbqO#=+a2L^ry^taK(~7`bi3~^Adi9FL>mj;=_k$uFFvWsyy@u55%%tsgevM^rRnz4~P#=7vX}+bd52+ z6u3rUpeT;Os#l+4Q1@4_8$&Em-U;%?Snjynx>&4IT6JO`^i!A!K>)!rOIK*T=egaP z)kA~baD_8LOLq-R^i4mj2)B73Yq%NYwnKqKHkOeMFEMtDDq?9#K=hC_;~N6Jd$=ZO z9l4*D;7>5D|J7|^LLXCraY-O(j!YIE9(M6;4Z41R9 z4l=A-`)|&H2CGIdY^JEv5T)G&PrVB_u^5##PrJIIwXUTsCZrk*JkRPTPbwby~w5_-YCXaXVmKsnZ)Qt#kC10O!&;2VZP<_i?DH^;zFl47&e>F zM&gN)i-r1hs)Mcf8iakNWC&!BW~`yE>6GCK;xzXSMqr|kj5g9U_o(hl?Eo}BlVG)@ zonI^h3>+JVs43p`bqTDzd+}_7vFe{wcr!6Q`8ZUuV9y+)DrGFdQ!$K|E#Kb#Gep;Y z&wdAaKFYe6n%yCOd4wj=e83mkxb!s5#8J4(z@W|7yP3APut?zGU~b;MOOyQoDX+XY z|H(*ncoZ)IqrLf33Y$!uLpf~>R{C598?mLi`mZ%I+6_O`rPV1ZZS zdXmS+Pi=;_#9;(UFOan7uXkgW%uhK>AU04z&8-Eyl{-o=Pw1$x01YZ5fNM9>+JE5SPKynYPtTm4 zrY3Y+2z8yQu*59FTG<=x?X9rVZQ4OlP=YmZ8hYwwYG;Oq5$tCzv4%r_E+<4AcKv-&5*z{C= z+XGq1nVudIfM9|1;Eka`l)wJ>))<{K1Hea~5zgt;FJ8sL=_O6nQ|bK#g1IQ}=0Fg( zK~iJsfw;&ms6qqH4!cVP@31V$s1brSBTcmFmo5l|hfZLP?yFL_MKlkPur2}8=)_C; zP<3QmSGhrbmML)Jc{2St>*mInzlW|`MWO_BV3TuDRar_$9LD(~G_MJd7k1*IzEUmb zzT^MI3N%_Hc1Kf(uk0PIMB?1N3P+R=Q+vR~DZ^B%8Oq3w)`sv1y}h(?3DY2e{fdC1 zi=IuZX-LdrLB3`2YN3SFNgR=Eg}S#P`H9K2jCd*c&9~IG@s%KvKcys2Y`24c7aLFV z>VSO(M+D&!xWEl*yWW{gQ@LCJ!ae+&kYKP*j8>&1SlgEaLsNE4m1p|rTKmL}cZ3MM z{L&*@g6`(VAroR~8lbx5XjdNwYG2K1U8Y5cO4e_V26FhL9 zdU>=S!)XojO2V?4liATY>m}lpmTR`BGb%~!AOT{WZqo%@pe=#3#sLUMNVmp@Y%>wr zs~IuxMU}@Ghr-j{1aiHCLm~0RGm3L;px*b6KSxpI>b8~J{KzB`%feC&K6sAo1|n+K zO`)%&1R7kK_;w(O4wla|DDrQFd@iFq;GpDD9&wW?Kk2n#?P%>idR#ax&LrlgWIJZsbAC$I%Ho5)8g*GZr07{Z>~ChzpmH zE1R-lQDObEJhpSMB{B)5$HZmyWgMdZ>_w9>s%CaG{_g#xc5E1n+RQf4&RCk6(?gODHh{4ECdN~@$trZW;iv7pb_B$FO(qDa z7B-Xn29Z%7|EFRIV3Ms4|K@Z~Y!P5^D7O(aY1t79@j-{oPd3olIw~87wP(*Fgtj7` z(l%|byqYC{Q|5aL4-x*US)nJC-cROAE=S*6cCYSfAc0h(b0E-b}NkiP|Xu zhs+4r76Jt!i{nYBpFI)`UQ%U#UG_FwEm0~m&hL$pNW7Nt9SoB5uF;b{Y<6d&!EWNc z0AM};3VE+B#teJAZ)o(CRfHX2(ljxjpTH$Fmuk&63q_J_+(#HSKojo*+MT_o8{z8V zg-4#ZE5+5raDH#4PjtT*2R^t{&KnZQB-!=}{0eJBjEUK@oxWK(~4>3kUcL0}>yDD7_o!~_^ zt8zC^h0ZP{Hm!Ph~z-y@3mLKAlbhy3%z@Oo>|l zM>#8_wv&${7DF_4nkg}=_rnzicP;^~T+OAcpZrYn5I;fzh}D!-z<4B0GNAGtnif7a zkvJJ*HIjz;AgTOIMNI&|v;e1dkVaE{tQ6SYTRF zfP&t%e_%|Yr( zUxwMm2Ls3iCJI1}mXb016CJmfmaRH5TpLt1b$BtwviQrjFU5?oktV&EcSpTD{N1ZS z;pb}$)n-aLia2r@f#R@kV2S5<_Nx{)*BYD52q4j@N7 z4Yi62r-3);`n%Mz|M3cg+bBY(aH6-29S77m)=Eps-4i6^(wjlHU=@I&@aC`z9ot1* z$QKCn9~SgUy`ub@qr)AB#%b#UOi4YU^$q@cvU;g~?3=}nTvHB^q8w{MbW2_A-qw7d z`EorM-YD_E$Ocf4W=xP~M%4IY>orkD+$Wzmx}U)uIvP%4#@uUHY}CM5Um?qFlaTRo z`u|5S7a2VXc0Bpa*Ox3%vM39qU~4(O+o-WWHsft$j=15*@BlEwtb`o_83n?2IE$$42Y6$h zfvD|NottF8jJEQ=kVn(lx7(Sd@CGmgPY8~2aO%<~*@ZEV{V29^j>E}^A)ra;3S5bYd5*{Id*2199;+OHf6>HNj+En~{PstfI z8_w@tP|BgtgeXTCP^R9eo*5$R=L%4MAkN7gHHFjgV@eRkoFg!(#9H8d=F&6i3*M&O zE-DHNVDVZ!3$jp$7{Y08{DA7C$!cB$oB~6=Sv~7oDNX<4WBIG0jC)I&V3ts^hjKFC zI+k)7<%+zgR=!p~>Pm%l79oML8PGt@iG|daJW*7S_$<;5YRJ)_F2Z_zED!62j(8n4 z;pLR))&?=4yrM6?g!$Y0jn0CMh|)?Jt_DEZNhq1Zj8+6ZSzf@-{aGMxPm$*}5@_B- z8wk0&WE>6>vq=*FS^_K zNU@_yD6b8401<5Gek53<5A(gVD3^6BByzd(RY@>%GyOVrEnV6oLO?;05 zPS)f0G|Lwx4qAy89-wW8d`L5x-sB;4;PD5Qk-Ed(+--cj+GNKmGI}^ev7K!g7T$;h zN?yi`Wy;UHnWWl#L3sVbdlLfs!9{#UTB6PCE7v6tZ_XLMS(!AR!SMPa00b>d!+6&W&`QBgQ z@xLcB5q~^7;*!X4A3X+Sq5t~3xi(umd`6I`6`SgTfNYd#)iWM zeI!7U0mn{$OesEet-K0>S=v}#j?=Wq?^BQWX!3em0uBvhJdR5EZK&)E8B5pK`-XmVOK+3UK_0X@L0xoc4>9A~wG%cHN`S#Vci;#4u4~ z^(=1{!hv&ZGrk%l?9dRzfRY1JY5@3glyF#?H?(gA-)jY0Rq}Gw)|<$o^Ov}o zUb1jew16+ek2w05dHg&L2XeZN2=TvsNs#2+zWuc^6Mm!_YgegmW+LqDBq35pMeLcXUsT* z3KCVdx+JiNj~iJNlHhol3_C$2ve{=u%8Fa+Jp9AL_HbPqnYC#hjYGHNy|XRf(d2sT zx*l1_OEuWjTC1K2ZzldRdVnd%ua$l68(EhFCqgMd@MUL{mdNj__}-18J+AU^-9Jto z;vPsxcA#x8^e!O_bh6H4$-!!YLKfxd^SiO14G{|0Kq18(1M>BhJViy~T5TH_i2MXC zv>0zkF5TV4^#BSz+SGJzvyXRabj0~cK`ymf4->v=aK!t;jX4Pxl|)9l__@Vl-y9rv zeJTQqr8)QF+1wT{y<@=Uc|80-PoE$8aqc9sTPBuSZnbDtN`^VixLs%|54DC|u6qNM z^mUrQma`%uFunzjJ2NeOFI$d5aSC&;L)TU2Zq};mpIRUkI%<3En*S6s5P zcI7Ey)cl#{N$Mkj>!DFCw-7@9hS_up+82+$|H30#p(xbEx_~1~_10c=uxeUf1_{zz z0iis*OVq@_I9}xS$K?GJbFcLBoKH6WDf~vBPEU#ZtihKnAR+RN5Lx5U9oDy56IQ_8 zgMHE`6OaNfNzcv$VX<{G>kKvjrT#4Tsd5~EeK$M?Dh!guIMhzYk5~!>97uMurMn5! zfsyMfPmc@1nZ$Ba&atvX63}vbUIerM_+RiEyn-KlhBPV^Q-WZQOqpzbN6-IM1mcAF zCf~K3EZ}BE>u>P$;`sOpVzvUlOz4fKG%9qHxe#P|^BJH*g`TX!dOK>Ejx=eAebB^! z_VUN_5Eno$(E@!!^u=TD0xg;@ook3lfUM-U}BQdGcWq`MPxOWk6`YFsCVZz z-f74h7T7N(e=z-kOly3qeRv6?=f;>vW8M<$V?nl(Elg+WAuJt{!=0jpie5>mc!&69 zhi!}W?LbM+I2Av#1@$C}za>BNWPvP~a@4Ode8rtqfP{O$+Wny%A z4aHi-8J|TtI#@{+I=40m!{s~I4Hx@xjpK(r*$w(tSOhlmT^sCX1~^uyA(?dwAI^Ib z`;mf^zst2?kFUs55~-SMtPryBkOpwQn3A0O(#DH(#^d_|0{JC=#6Pc!B5Uk_Uz!UG zamsOtyqYiL@5%i5L*h}RyjjPtSpgS^5{a>y2z9`XQqp~OMJ8Rd&=OGsk$i%#f7ot3 zzTub;!Y+Icg*eGP?A>@F186U zy+O6iDr$`4c`w^rz7lQBo2wvdY6+t`@tcdX#}?ZCfDx2*%5GS3jYy-DZ{EMvY5`W> zzr+gaA!-8nr^T=32^KaI9Xkv7-B68#fn(!-`K&gvw&1{H?!ye!*Zzhq-sIapyjK`w zQzwjMPnr=m7+TD?y?=^YXM{CpoOSHYh^6OyfL`hvu;qAWg*}G4_w^^1XCP!dfw;WQ zrXm1hELR6a$4sg=_@a-W37_-72!5}Pd#R*h8iKQ%e><8=Bw5nQnwGk%Hcucm+LY&c zVJFLLb8ijLg*~Lu`h{p`Ll;>I?1)7!#>WgxZ}kz zWMuz5x=Atx`O{a&DiP@mH{T}P)sHa~{1!$}fhV=pJFW?1My@Er9r)yFK?+_0&_FTW zijU=~OtXw6){MhUt*kpNha@t6dO8t2S#+^rNfCgIFE()g*lgr)$mV0#?E66J4}yZHK!tX zuq{pi6${xjFQW#!Gv8CCIh3i?Y-KsyBV>Ml&I9+wADnM~nC9f7*qrKj#~<-2362?p zQV3u1{onrv6Qv^oI#&n; z1Oc{`wL+!nsDL#Wt52uT~IZv_Rp69!Xvl!6@hMZ2~_R`XZ`O zo#}CvNop6we)dx)yRe(%2AFAgev}<4CuV#`h*)TMPd@)Ss)~F8AUSOgm|5r!MfXO` z^Wvf#aK=HIx^Q48CN56dm%N%u) ze~XT=!1YjQcyTFlDeDzH^YJ*k!@@{|t zbKF?7WvZ}Rsu&^Z4(N(cLdSDeRRHF36W2Hm+~VaVTy1T^SoV(7?`C5o2`Uha5K4J0 zx<<}7XKxyHzuaF-FrIvvNBF`0@T_T2kk{|;Wf_N*<>(aGNZKN(gD~oRDK4i{5(`?N z)LY*=hD#%1g_!Xe#6PHEvu?^ipc>P2_0p@4Kic0CW&@0&QLE4grQ3RdNfl>R=n%&Lih1sGx23)Ye_ILGOSb?nA-wLdIcOEcb;0aQum(6%&9f&JG_OKW@7!76 zMtcr7p}!>5Ukc&~_vCZ}IEpUv6mT5YBNY;jK7nO~ODXmvk^*eT&t0qyBEh zhpu#s*H%11O4UeGCv#AP_#06R(Ed4WyrOJtvt!d0;?eoc-j~iAwu!e1+pjYnDNouQ zDz#_MX^-To1Z1uX??f4yB@#<)Q>g_EIYX8+IeM}ha+#*i zz?JnaNx!SR)ca7-U^UXg=@}6B*Hp734efNg@ z7D0Teif|n3W-zg2K2g*Q!38t7F{fQYwq@~daXq%_@2)+wXEF|hTV(=Rs)Y~Da zjyoXU-fbXd0;1H*IuTXSXOUAxP(Y=7Ij<^#F!!Dwg4knbJbO>VfjR*Q^D?TawB(Vj zyD|~SGEO&0?^nB?J)u*1KXxc;3%8wpZ!5g zJ|zo^SlJZAwbhyh)gyXf_7%9|Ay8QsPO~-%6iV#ikANkXdyd8Tm`88M&b#Pr!CR;Q z@twQx9*T_kZq%{WN@ma$d6JnE>LxPGo}(#tdgfWDHQI2cFBNjuRXGuWM@QuDJ9$I- z^R2<^^?rlWvres!$7VItG-%p}1TU&^!8}Q=5n~dOD_}=)JJS1p?o^)Gi@=d8#yCQ{eH{!RJ$I3i_6D(e8~$L(b)E{Y03foc5R*=G=UvB ztU0_-v+6~;Ub(>7kL!w*l(W7pXvQycy5l`o7a!8V=90D&aQ zXh6exzubS`H5O{=6CPUS1At~6R36w(dm-STiO$C%E?R*s7Ejs#Kmc6z2&d&(kj~A)M!#I|l1L<+0*z)`m7q4i3`RFjlf0-V)h+sv7^bLHjVsf##?G zZL{K543E?Lco(H3I363p)PyB6|C7~h5h#Nu7QVhG{r78CSaQxCAW^B1n(6YPr@bM9 za*yN!F^~-$sYQq3XXI5ENE0lPVfB zGXLfG6Wpljl^)<+vjoT?247wq9O1MzILB7bAPVq=xZEU2Y-JkyCgY$ut$hZ>O2e;~ z%e^Qzfl$}s-NwJJGoW|N5GwY3g-$W+BM`sH8e$z{epE zt4*Re#C!TRs-@9X?mjq6Bp*N&A@}{@S(C&jlhAEz3^3QmXF}qdDYI8zz`@YXugE)B zR_Qg^I#ZGPzOpwZJy1X0Of}|zt)7L33r#!<+RF9ww!+QF`JS%1RhgKf$dO`jd%@P| z%tgB&uY&|TMer*rWuu+ksAteojw!vK(DWiBOT0Ugt_dj+ z8)~S|ilUfiMK`oTPhjvil|X%Dr3vkg}6eo^#f7z zZ(4mmTcI$b@2A732dN_#6knbU8qd0%fe4hCZ%_=&XlxB@MY78 zPx#i!j&-SA;%u;Rm@%C0(?h~@)aIN{+JvYx$=8|7__GH`@cxUK#O3!a!E?$texT@t z9e-k2d;x>*7Y$VxuLcc=y}XNI+e<-9DIMIvJb=T0WdDx&g7vMqgv%Y_0wTfiSEvF= zW!pyV?=a-Asei8>uE=7lBkD-T_(~)gll`Y{MXa0bwOn1ctm7p$$djbz9!t4vKJ_mo zvIY&)UPzEyjC+#^*vzM9Cp+4R=eOx+*u%-DY&NbDqxDcqH~aZ-6MNHo$3r@x;Gkuo z0g^~FNwOlv<)H@i4;9(I*1zIYO;le|51A4ReiOrDRTdzAgiMbz?F9)HMYTc^xRfn*Rv6qultY*(Ml!uGE^0W~1ZKA~fHKyj|B|1NM9Z1goqAYsn6BH+ zZEb7rz5h{%riw^2^}8*~bDpH9`je>Xm}yBko5EvCDS(ewDr8t1<=+?*hS4<=a|eN+ z|8~V5d;2!3#AX$874V|y__|?<6&hS)ir!}${FW@gu`IaBTBJ0Uy7X~OVs-bf{7z0i zCyJ{y^q&yLNsryq?607V9Jh!0c2-i%g2NlQ&}zM*CN^8h+2-L^d{TCZB@$5|6&Zy< z;A5ocpfmJrX&ShgYy|)eJG#SS*}kI-H(Y@7T=uM6Eol`3w6kN@<7mwz4tw14e)Uo- zc4GNz;al{Zl9TZ9tVbbVN05m`e<^{wMd0Hd`^^D#79Y8V3;~PnzmniLERc7Y3U_52 zsojgO7)^|+4F`sDU;*SkXvpkBn7iPvQVLFG`vYB&3E7sK~Dz zLY0tuScP1P6*1W%BeFfNj<=6VbHClcX#7q^yVm`Flo|V)Jo4a;hF2`OFt0*iJ}Y8j zd157|ebXXjdUeC2Kjg)|>}~k`f2XDtKb;QeedaJ2_>eE~XVx}^?il?S%#zw<2kpj8 zaVj3|3#@~r@ndrA!M@u)(>BEam!mQ9Pqp0C5bCx z7dnEVMm$xLA_`jKx?SaU6%FZ}00obh<}Cr7|3_q(_+g?D58AEp&6hAAjgkZ!;jLQ$ z{SVIhKsr{2@e++a!X3KN8fc3*D$7aMGG{$mX`nLJyLRHX#q9e$N`S36sTKdAU-rPS z;x+QK{uLIvy_)&VchQ8@uhBh3%^{``)mpH35r{Un9M{xaWMXyj5`U}$YzO;e!xmFB z)ljKlIB#IFxjx=_Q`R~!tG_iu=Hs_W(MLbHnVeF^Z0HojnD=A=Zrw}avXKR_S^B7G zrG}~OI(S`)7o`$ejW#Orx@%2lOe+0mVrWlxXf;PR;tQ9CfSB|EG$p>?$?B5AV|zVG zyoAYxJW%d_q}oe7S8SKd-0P>an?yMgXH8-01Q&G7iJot}ih{kK__GwVm5g8ki%F4+rk@P+n$)i&R5DxE zh4l-jW{%^n_Pmq@%uzJK0Kf#6Q=a-PZY5EgOGxVJM2RnylD5w?!RcgwTJYC66wmPZ z4)hVJSzBFK0(!nK3Vevk#jap+9w$IpY7f#4!#A9fR2P(#<^51^#+y&bH1kDIeJ^4* zn!f=SAxeOs=NLD<#y$K1ccEEaGII*~daa!$l@;b%m_lSWF^K`KOJqRZxSqJ|CgaDH zYMcpPB77?wRo$nQMYw#FhOe9)w!CA{-#phYnm$kWDZO%)Pkw|J?vt|>ny4PQ!~vm# z5pNGfvkW(FD2DoCEUDmv(r&twrAP2buY@Lm)zi%^#@MxRY$Zvw#B)XfHXPptG9e{5 zXbJCUJ$6()pQl3Xzp9l-Rv?Ocq~iJsN3R9mf!sEF=vWZW%W$!pB6D4E{p*$dDf{wX zq7z4Y-)2bIj3RYy{u00ov)iWYo{7OKGO?5lVL5eA*_T z57puRKSHhARWcB}Ljudk_$etVJQp1$;@VU7?Mmz-`2vYI{L&A;4NCjL&3d>1$`>I!^8*^0yK6e5Y%_rH z28kSVW7BV~r8qVh;Ym^NXVk>UwJ8Q;fjPfpTbKU~*cwCZ{PL@QLp{#VYg0@lTU+XH zGB@gc<0aGi{AEgIY5i`j&cr&0=b zWr`wRPG=P2sA~o-Pdb`Q{>_Nt$^h6%1f=RLFeg!qhSh4 ze{)v1k;ud>=U!5zv#}9b4}nKu1Nu=KS3AREGuMaJou1v^Wy(>Rv%JxE*HTJ{=h9L* z>q)X$Vy06vG7z!ZF`TCccim!a33sth*gOd6?BoJNz z#nM?i4KabP0cvT-l0jn+;ILOBQoh_um6A*3%+ya9dw861&289s;AZ1cNLxjjP%lc% zT`B$Mtg-v;#lx(M8B4*;S>Z{5KSK@m%fA1>;|oMm-l3{oXh@1^(`el@x&xfgnn*VE zY{nkCdM-k*Xc%14Jrj(rb(&B+$f&m3G6oH)@${S{=w}ez#I$7&CQbR}!P-FBCQ_Xj zc*YtMi4s=2NVy?FIX-)Q^eD>vP3Xda zf`e5*=idDKj?6IEJE~~5il*T-!WyRRteB@4t-Qda5hUrC zkMu`r@k`u%>&LGPc1d{zK^nr7b^CQL7hb`-q;T=DsP072B|Flbkrvg|A3Ul_canp;8MNdccmVj6H)FO*+TFeQ8fLw|8mLk z`CDnK83$s*+d7I9y(^Dyo&+)TgSggzDj}-1Q+Kl?NkFK`3Bb?L0S$2ZnZva?Q(5v}`(gLl9{3BUgQ!3521Gr)b|EG#Os zYGKw8l|ckhXp(R5Rx#BZG0!Y^u zycTIFhGB1)8`}WrXMxPOEYo-C0|bkh!vB>~m(~UjySNL(3rr+qgIpR6y8?p->I0CZ z1P=ImA=1+)3O5yi;--_53O`EEYg%~ecO`lM*KFbD)GrZbtSTJ>t7pxvxPSduD_p7% zJ?UGU)Id*;tvk&12!;g(swxI4AhsuEIKA@WqW23v6AqDR7jr~fvk7R~W9f$x%VavV z>S>T22$ABE8uMN8yEE*hkHUETTtW4YruouJ>5of=-rfVNXr~|wXD&iI4iq>l_XaXx zOF!t0u4sW2FNy59cDMHNTJpcSviz$QUG%4deQFcu*<7-F8nM|IA=(o(HlQnsd9(T+ z-^Bq0uzxy3BOD#VJKUo98;v>-&GdQBO8JDSmRz9TfDdEcf-ntT`mYhj_uT{UzAq^3 zj3h;FY&BC~|EV435D%z<>F?<^2)?o(_tZ!WWMu*20El`SFoc+~xk=bfj*X^7-wVfH zL0VA`ph4k=<*esh(h_~@O@_zS+x{mFPD7LsO>Hlfu3DHzs*`LhxE)-*gj=0br#iP4 zi63(A$g5okVxs)=-o`3pKt0N_SrP$4Jkg50qB4Fd57d`^EO_@WH zFeaI0u^&7{;C7lbS(g6IbJts*BB~R_YY$J6Z!WbHAXeuyOnA-yE@hC3@85d1gHcQN z8|Czb;WfpvO9Tmd9=A6-9FfLCTLd>L69?cp82X{(s_uX@+=`)60R#u zyetEmc4vIr2tQRg^XYoP(6JmpJj@hBj%k3NdG~RcTf_=Bh;4cQyPdW-casEut^sjq738h zk7ig5O?2mGB%)xv7X}hCE=jh<3~Rb?#BzZ!-fL*QeT;=H=bj3pxFt#?@$hC-U;qx?g#r?cp%b9BP6$-A>xdeZul%|6ZV9*ktDS zj2Q5yhNa-#H$E6J!nDVKk815Jkz7HnP=7`K`qDUK&wIWKLz86i2AZgD4tRR~*xhB^ zHDPje*T@#|{5w?Kk601}*SDSxRc~mp$pnP0tsiiciLb4@QDHK1J=I^Mq^{!#?u7KX+NWEZqV46HtX1V@m1L)7iBW>D67{d zp41-v*X$eQVJu>Vle9L;nm6B+08HrgZa5|-UbyTK1gz7rq%v%UPWrAGQg z=jbDmZGq<9P0+fw5#^+|00A3+MzvYl2W1R}v4C4-G=GbxbFz@439esQz2C$1(&3S` z&idB#SiSr+jRCcb+Y>P;73WhkB^>fAZi$W0$wZu1@3YmQ*u?(12YaMLA(6z$TTO~i zr!%1AL??t@(%p?U+U*5uCavi~^pOzfkUBpGUE_G^L3+Yu(K4<*ITIXGCw)>o0%+I1 z7JTNYJ#RgcVwB->$dgdS8WY&ru%v2@E{S4|(lyYtM05^3D zJa#{{%|F*Hj7<%|l!u%OJTPU~dnUYB(gPNFBc=haBF(fl++;A?b9AW$FC-8n#}ibC`x@*_RXqxQEqbA*1W4=TL1L z7@NdXsz?tclPG|hDxc-NYv6=H`n<5deLn@~k>)`X#}in>wvoHgOdF(s$F79o96MNk zpP)(rEaEYgS1f7|;^!BGUujx(c^8zR_1okY_Rn0*Z@nPc`y2W@Zztl4K(yZ2D)B%f zw+(E8&{BRs1ZKf!pR9qY(93$|UL|n9OWjG7SmqwtJ;_ok_!Kn4P|1C}4|u__hdsO9 z;00+k#|k-7B@}-#@iq1{%lk{^L!~CRy_3HJfHe{o!Lq`;aMg6Vh#BjIRiQO>oS9Lg zM(j)JvkqQ+9^u~$r#Qs>g>f)71G}&U*E*EaephX0K}o6^Z@~ULYkdi}{OR`p-a+2$ z6r-vc&yUJ2rXBm8B_$EC78MP_WlK`~3`*p+kVD1(rgcNbzaOe50voBB15UEkFZ!zh zZ#X0leQ_A8_VP#>+SjIBFra4m8te*q z8o3C(cqz}4Dfy}x0y;}UdT)CWZCeMa9u8XMK>%giXN$NjP;KpAJ$wHtKM|Pk?xO5ItGS@O>vadNjBasg(< z0ZZGQI&U+NV;s(2>u2MWHyJW_qV$@v>>Yxf_tg}_9b`|{%|GY4bMB}ndh&NdEm{zz zIf&|`UUl}g_Ja4UX5fgVEl%<^a!E3|CSi;6_MM7UDIbg+EkpkimhY7p$uMT9Ba0At zexQ~yDt^pd>>3_wQmc6y&K6g_J{7U>)FH$YbpY4oXgM*ow-Aav!o$`Y+KvCVxM9wv z`394GEu)93!oH2K9N@F<~@DS+? zrBWD-rAees82OU>B#ggP8fx!#I$^^7ciMys#o_z723z-HPY7D?*NJJBxQs)nrB; z{>3VV=XsHx8)LFYKjH&bv*e9{i9lyly_#|0jD+(X@%6&*M^Y_GP}h%uK#U93V+bcH z3mpQV)TEWkcZk-0n8*@%Vh2k%>>b?~rW`m5Np%=T3t`43#ksw5G18clcou=XxZjOi zXmuZZF*Pcw&M}BS3>U7)J5N0m;NH*|jUnUwWH)`ZWo$qW57RYjTu)>;)W%fJ zJYZh0K^CSZx^vrzQ>Oq(8^0$&Yef_c;aiKF!1$Hodd7qZx7QsUdvCBgQ6xB=8VNZ2 zA@?xjy*F?wV^s;ea8TGRv>rU7n#`3n@0pjj58<=fO~x-qPyd1ozgKlUSD8X|--0=B zA-n2-qSr;lQl@Fm@wA=6QhQGdu?ZucW>)u;#}E#erp~44mMcIq>hNK?f|*SzBzCm= z7L1N&^V`yvyIE4bzuK(Ynje#ALkn=VGVZdn@-wedQ2w5MgT#qB-g+A7ipS^%H61A| zbt%3_%4yv&lTjUgf~OF^EJ3wJp+OsU1Vv`$o>K}j2^USP2+~b-w;ffv?2}PE! z{C7#M6l~A-nIln0Yo}{QdoyQ#YO!!{nJpZKZor04C&1&GVUaJR$DeL>R{;B~ks)Y^f6y{VLLxF0v)gq;km zB;PGxXI(aRfC1xF0vSp7Ms8YM%_OWBe2m5}#|*D%VqGV#weg$W4+u%cHXA2uekh-W zR5Ar>te#(EGd)#*{^J~(%<+pmfA{krJdu>v|SxGTlrOE6d?43hoUjxzD zFuvQ&NV%~-6hq6oHl!lC_q##4m-YwtqyGKO)--;rB-FvtD8kD*sUixnrLI$bhwy-K z1mQB?V0t3BBMS7!MFZHu3%%xlO~$C@YZIemN;k5&^zjCfT#QT4kHu@@HZ`PUj|)Ia z2_@2D%?IGo;Vt6K-oi(5rPFtmBHC#>gyNt{zAwxrIlP=W*NnMF`kc4P;g!tCVqm(& z)lZzqo%|&Ol()xwn=`7Af;~)u81h)A{Pwp-io`ET<+xuPIsbp$=lez$f~o$FHA2eL z0b7&A^hs|k83>+C5(_D&ML3!??C85k$5ik!B3X5ce)^};Hyoba>a+x~0uQ?V{zeu# zA|SZpDrPO$oxsBe$wLg|*YE9b!f|Bj$zj?;-#}5LvkZ^(U>C11Lt_?vh>0@>_jz)@ zVwQW$zmb!};a2sUJXTvwW-X=HfuEm58`ydOKZ{F9%!1rgG~g8K%gb2^L>FFXA(J5j z3f-<5#30MYY~#QhD$5qfJ@HQ^Az9;+E3E*;0XOS|&jN0V=v#jzV)aJhJxQ?A%zWhK!8wW43XIfLNFsJh?xE$hkP7l%4H z+5Fg-cc;b&j{+=8Oh=D@$`tXjr>})w;bVh;hEI6)Ov-r}a&`WS-5qzhEZ1I8@2v4E ztp8RlsnHZ3F2e{~g~ty*kdqW{30qExwV)N>^Jo{lRkbkM$xnpvl!zYv{I_{+VkKZ@ z`|P(>?00qi=YypEUT>W^wW*^WWY{vX+ZWo|3%4W2V~l^cr$GpcUh||gup^H@=K1F? za1HBU#5 z^p=rdlE@9f_R$BFQ0lz1jcWvB7oUAA&-QzG~1I@tIgZGt%TSl!h@Rkm|3QHbj znFi}*8?Cv&Q2L{j1g{{A*J-aR?P3WWMBc8gN@~>tBf*!WU|JhlYJYmDu*E5)qT`6* z_8Rd?RFuKpn4k$CTSQ{68V)6bfkS)y%EpZeo|QqGY)7C5;l~m6#x7O9KjX*Dxrjom z6g7@~(`+Uz$;9J|mn?)<93L5=FnBh(_GrrKfSR?<#si-+nMtvxpbDc?_MlAyHG&f? zSI45!Qwt!TX*<2m6vkojI%p8M^}KkhfRN{dWOo{xKXfy1U&ki`k8*gR0z@VQ0U3w& z2c1VEgEVXa#>Cv93oIGy|6ADb5R!MkSfss0*eLO92vibEbgy@#uRFxmnU6;m1xZPv z^d{UK;WjIXN%Cy6Cd(8}yQ?Z8f#OFvP+%R(NKq#Iqb|Y`gypDvebw%mD_GHi3JMhI z4zWYCT0(L2?NO;D#Ncl7a-s`cPJ%{_3Zncf@pyEiqc%XiOA5%2S=W4gqYJHYdX0f+ z%icR$s+atyhD+yBlj3p(8gXxN<-g772c@{V;^0+}e){5~>-lkUnkK>FM!K&uTr)Z5 zNJs;1r^I4agm!{1B#w>wLNb*IaG}pZ`<~$Sz$aKufQKL?i}&zi*!#fj;V82U8ID02 zOjJ!Ew=dO`S#Sky@JUWn)K1SBz<~L*oOz=VhZS8Pl z@Jx&M;teC;^75t;3g7J(geIA_;tZOzi*bSbw7n-2AjAS;lBWcc!Ly3(k2Txl@s)`y z(F2Iv0+!aYr4zZq_PD+sMlGBYWO)-+U&4BH!42ws zzkt1aX4QwHa!aA2`6s|(x$gfds&!!>oCFG25<6qyCrKdQQd=UU+WFD;E|b(SW#!_F z$PiUf02s_81axR>z2v|8ACk#l{+K-)Y8LpmTHx z7f*8Io4PDawVlM1RjM4%^G)*tiX-AjIv?|#g1(uP2-%HbCt>`od@rS7qXePsUnTAX zqR#|PTEoxbo?Lo-VD0!_OGnnt&p?{?XkpTz~2!Y zW~=X|Y#7PSq;R`>cn!!egEJo2*xf!mnk)yLv*FDiCf04Pyx^)0^CgOuFbtm~(3}K< zvFr@DVwZVZ$FB7RPC2ogREPXp=2CEHog|Jf(u^1QZmvPOar@Qs)wsliRFZemCrYi65a~Dr*09V5Tk6M zfn75n*yTTGW+S`<7Ufg`O1%M#^hYbd zum~LkhPB`F{u#BXFdqrDnAwrAp`Gu2}AoTsAHn&s-4ANxq|O`s9qt2POt@B zZ!x8)Pgv!Yt7_aZfnWz46BStawa=Al&^ z@S&n-fV4hWQ-)SKv!@y=zYk|4jgN2t7~;no+`&pM%~y{<^fS#iN0j{uFI6$uSG>x{ zrtwpHfg_5QWx^nYD^&rC`;NLhip$_ZFNH1W5W*pl=_S{6uq(UuR9Nc@e4=au=8f@^ z*=+&gq-;HiyKtYXMwaGITZEkCQ8GMj*GP2Na0SZ#*@cb8yN}kw$wCACexF0>7C9q6 z0=_XIl65Gl=VxYCWpE9hMGNWfdL@1vm<`$|5xKynuv`T!9#1TvGRyh}GtvLEB4*NU zRtTnnjiiK@vS?27D^uee78tMRCA~{2=d|bbF??8Es{5@_(uxC;33d(|mwYD{v>BaW zH~37RD2K&OA@T6XZsKVK`8og{BT*jrp8iV6IpH^a8ee(s1SV}1*xE4*ax8){rNhUW zNuihF%1OonEo1@4zY1s#2`u-Cr7y#Fx2n%`_-JJL9Xkm6)Z~+w={AYMhJkRl<5xH} z^M6XRF5k_V(uLo39@93WNDL6#?Ure>oVnwwkX&*yik2*I&zD0tKYvY)o=!~P(V1@j9T z_i|K+A$+M-n0N{WVntLijx84op9J`oIu>2wty$dl#sA(KaHc1k1?!$o2XsoW)o;60 z9~;Y|;(AZ!6jUVi`l&@!7=S_P#6frHOzHh$>IdID9eVqtjF(70g5aWk2U2WFIMEb% zJj`KZ%$4}(^CCQ$QHh^$L+C5GYJhi|?Ek=i>q|0|Bh`(h8mUxVy5=8l+y z83w6){aL`P$wio*lc?<80!`^3ftvt5DH(ncoMq0(tcDs)IDj`uq0d23>Lk?O9Pwv#nr$*sPC$8oPde-*3IwF z%EVP(Cl0Q75=$H6dyqkoDtievQ;tg6IkfD20xuym1LZMNoR90Wd)Wo%?BN{6#q~E z<5SUcj!fR=Ic}*_L8}XGcxCpDOJx=`{)9}?w13<_X#HUil3y;=<8p-4FQJX~Il&*{ zPX1uhglJueu@ec;XSFSrcik7@_s8jeO*9`%*yim4ZrG#~I}Wg1vNz-@dJZvo((;1g zwgJ(nQA!g-KfN$;)B?hn0QVqF;3-y3iZ%ZxIvRK%;U_?Pxt5^FOUY_ZzaF;G!U+|o z%PDhfO^mK%h)>bnl|D!=&X$YsDajVEp_7U;%PE%8S9n0b&s6ECIj77AC6`wgsjqqe zCNE~LOjkH#VL8y^PBlweDp`$`Y=`jzdxqQ&S5@Lpigg0c)z&+AFPYPcZaJV{;+X$8 zMGp{0G%b!fReHuvVL=LJfav~<;Z3kmXaf|ZZ}B{30+L!1HQT{SHe6vo88l7mTM$F; z8gyo7Qswbq-ma>wg2#-G{}ILWDveNNh!`FeiFaxa?$J;3i`-s{f@u3jhlu?*0X{hI z&yeg#m}b)SHZCmaO8?1fz3D8~KjliD?Z7y31t3h~>fkDR2tuSxit@0u;;bKhaVqK~ z$Dk2kQiKe+7BeTi)sguI&*}y_=Hw>v-6eUtFJYIhgzU;*p987Fgxm`SJG%1Q zkO;BfJ8NrgdheT(9G>*KSmgn=41)G6T+u>rOlTW!FrZ3P9Lx^Ady7wgcAj#W!{V(K za*o4e+|n^Nu)fux5*BBVhBi1! z%a$!9=b6aZ#x~+B1m>*GuWipcu*HG}SyC!=$D@*LT7Xf*vjTq*pZlAsoH$=-K1wVI zUe&_IrzFRXg+|v`0d}++zczAFafvBbQwD~)&-V7(dSeZ-a(FSQ{=vA{7Qn%!p%nY@ z(LhC(N5%V+H$xV)|A`C48~}iFeCSw0UFI_l6z$pJS(HdbHJd*(dbET83do^&XyCmL zJm}2!-cESx+Zs2eB$5)y^5g7C-9FLGya_#iyey)!=gT^GbX|WEas_zx4KNqJ-}>a4 zxzhud7r47CF4?DFaS6c_cBKm&ULFHH^MjnOE+?G7Yd$s{*Fej8#B6)bqGe7;-8LXO z`=fQzk1?eMoW^k>i{U&{uDPN34G5BxXquLwFtuH1o{6=G)ODx*kMvp}2<)8s`eqRu z(S$Cf0SnZkrLXYg1TwA$bicR>0R`kL-8kq!PS61AvFEo|+wR!;ZNUP--FNWWul_%; zWfJmu@)A|<0&~I>Ax z$*dKPW2*_A{Py4gc}uDs+4H@hO8D{%@g-6gvuf>&5WHGbjm65cz<-LGbKG_ou1F5; z4JE5mB$_r{ij??VGLkJ!i|^5H2q1L!e#lDog+-7Yydz{>TBkjRHbJNSR8jscjG(u{ z(I{z9;yb-R@z{AVsaV9%hhVzm!Ev7_Y=27?aE&gAF+t{UI;SI>9X-44Wfijs^1*uM zVyu*qau~#yF0x69Qo4GxpA*`qY9u54=|E^v6qr!5uh1EBpl-+{pmKz8tmTgqyFaD3 z4O7j4dj*R+Wj0D#)_Aj}G8I)FrMC%~KCGXw!;E^^>m{ObJy)G}Q-jdhP!ifo2)C#S z)%rv_%^-hE`)LfzgMQ#}R6G#$9_)C|e(9lp4QAMBfFrWL)vv9-w3i+8>giN|N zVl%=)z+?p$)El1Q*qu?MejSJ##y;J0bmsgtjtEe3j?i>$s-GFq5eJccS@F+g-0}Qe zX9rIlDfnm&`mdqB@}JomKT)$zmRw(U<81L-s$GGj>jESn+@pG^xc47XcuE$qwk?E8 z?Ge{IwN8crs8l^x(83`=o0O$D(Tju_KoDdC2<+iq!sW^tBBl8sG2j>%u!9_V)D)W( z+}DMV2}3uf8M)83;dUYtOk-_SIO)?vZ{4=WDoAFk-24K6j5e#!>n2I~*dC>Ft=y*9 zmK@|1B0J{2cyh@GSfH4N>1sygc=KplhODMO);uSgm)9~M8I4Lmf)XMhlS_v@#?)*p zwcnPeeazfjb)Dnm5|cRTwxQ1i{P#H(MltaGp#r9YUvmg%EiGy5o3z7bnqGzy2|_+ z;2X%8eq%?+EXz?oI*2-y_Oph!yu$uvNRZOT_7x{Pz|LWozgSaGAXevpRI>1uH8-5g zpL6U9Y6YltOAs`h+4rI9p&4Cew3yUWe|N0)%pe6w!v#0+Wi-Gv#|YLZIx?l;2F45~ zDb{O)?z()AwT{?hUzcKpc?QPoV#TEkzT%qB_F0rH)o)%yz1oW8Okye#P5W`4MgBY=Glmsx z6-AwLCwDN6ML?t*VTpYR9Z{rzbb;_0JyqPm%6Wme;tf9NQ6q__mrR$t$$$#ZaeY^m zTB=NLP-;mGn7$xz215}4RZZdX$*t@X^roh|js=kY{1ZJAr}=QvJDQOL$&gGiFUG&BkqyA;j;}qIL+?V_TqbK_yd zOl5Jt`f5N)ulD-Q-@&p(%!>$1Qrp57KTioCoQ4sq1ZP+TUY&LQv_qs8g@GI482Dq3()#IVP90LLfh+>7zJBztIOkYgMrjG=IDPv z?0*%MV8t`Mu-hM;^%fI&?Fn>Z~ck}1g zRLj;{LV`m?Ri3kA3x*HqFQ_=JU6{{{)K}OEIZ}K<2VZFCWao{#Nq&In__?(1A>-<$ z9q&!6BM>|7ZfU1T9f%hIl~v|BBlXoP)3?F(sfy1kJh71IT33DmQBp%(5ncn_k6y4k zms`p_IN3K-T$$dN-R5cF5EA+5c^`?*TTlX$Q19HtP5Z+%DT**IY1y(*dGt6$Y;v*2 zJRfURL=U$mmEWt-*xCd5ijicfU-HVh$pxGY+G92XdF^SiHZKmtN(XEQT8#Q{vu^dk z`n6Gf=CTK^WEWCILo^>-ir&hy2LTkX0WeRpq2iVsjE20mIo3EyXQR6~@}?BB2aGCb zJHtiwR-~%cGoO-9DgJDY0`@;Qp{Rrh>Gl&JVkYV`C`>`}Yi8RJB0DN1d{|LmSja|; zL}`fiC$z0*ia|LWpS#SN50z86P73nt4<)+5|mF5Uf_wz*H7cQj| zwW0}7`QQs3n-w~bP0lrwIAw-Uvcp2B+a0*~92kQ)cNo~)!z-x6iu)psy!6V>ELoDY z)nX2w(hlQn%^PB-F*5+TDD3b)ZLvh5r<;;}GXdL}W798D_s2Zs+5;-dh7Qzst%NN8 z#a~soNtW*d)9Uc&uo5r!NH!{SLhozG+63&RB$~p64wp}P3V({R>{sMCQ^cN<`$;bH zOhxMur&Ky9yAERKs6)@{a}_fv>G1~vbIl2(dlwvEP7m}U>0e#vG-kSMf)zshHok_P zml|hO>itJsR-7ObL~95iLxL7UjNtz>Pyz34bQaG?`rBERm|~Ae>bB+CMqrx68^Ewp z@Orir2zDc&lO3Ppo=_npS=~yd%gRdFHOx0t3%|huOOfc%0F$qiKJi>EAO~b)%X#90Tz#B?LDI$ zuKHJuVFN^Wr?psA!!e<6%SiU7hLdLke|X|UzC>sWmHtqD%dr}cDn~{HlBkupO(GRC z@SBP?`2pp{jN`-a8-u#~U;NLKwSEj~hK=%Bddis2eXDJ%!pHD9Q zLQQU0aUR=Zrde7%I36zO_k^^NoHnnhVy=@!R+tPXsrNuphOP@WO>tx|{$Wy>z|Gy1 zQ<1;UlB%X-`<;id!g5hg{B5R8GSB8QLemgZ6aIm>*LkHFkZpaOw@?oc4Axoo741%q zu)0zpj^HWE+yx(BLXO(2R{NF8rBYaquFlyKe1250p=rnrS9mj;-*fw?iL{ z@`9|$`;Q$Sqx+GLZBRi)_Ddejl6BHJKc)g%cl%Q(+wuG!ZIuQCriDdlJQ#JTeMuK~ z)tSo6stuv+)J;W`d{sGY0p9KLo^NVf5JGhCH^kz8)^ay*kCt?TvE|;|aC>b&SK1Yo z_5%g;+4b*UG)HwITt?zEUf?-p52-D*OS%O%3_`#5KCknmskHeyqV6vT%v1I0*{;$y z3epT~(JV-Xj6x~Unytdf-QIfN|2CiiN|BiWUXP5Ed~iV~uFIgvZ#sHSd}5ns0NtRJ zKBGN0*^Bjhz?cp_oV9q=+&1~5M{iKUnP4Lhqz4o4cbeLp{xiYyU>NDA;kL;hjSsJr z-(TRni=_0LkU}}gWC&Dt!tA3|K3vX&MM&+X^_a}F@z(R&HlhQ#;+Z z@BYs^IU#ob->KH_Q1jry9X92)*KgNWE2fd0Fj|Z zqgWkxfQ9&cz`c_SGG`_Xq#S#mgna6^YjCI`_+TluIXE8WWkp8`==83b`KdOzl; z`S#z58bhiF!(M)Y5bH6>sE4nN3W>;PatP_aSfE`z2hyq&Nk%$+pj+n1!=~NH;noX3 zjt=qu`qdVUdAGU$i=kYzu}?9bqo}4-gCs5K&*I+h!^9Njsx|AuB-WE>$r8<<+~J%* z9~d!9{=V=buv$^e;m+$Suk0@H5<^XNbt=0^Qri}hPHL@t_qTT*$9lhvAak2{1uU8t znYXqLe`)r%HkQyZeEAnWwI+M^F-u%_vR#=}a>k#*{4Hdd%f?-CA`#&5CkFpCubM>7 zv_;Kuj$BhOIK}WFK@7GK*-9Ah#unN-tPV1Sv6mEfR+Qy})kS=4`~3n3>O%D3Mo|t0 zKkR$sSk-wR+0Q?C`4{5P)fvQNtzduEW4!wL+Qk_>w z4|!1relfoi%hIdNar*j9_tf(%j=P3r-@qoALUYBr-E#3Xr|nLSSF}5>7Hz{X1)Ox# zQ(|rShBd!E!~%-qmi6?|bdGFS-xEHe#OXvgKKir9!b=-C@BA3*m-7kkpXUG9bQm4P zq?#NA3Zs?fe>@O}*G0rDoxkS8N{?;+4Ec=cpffOMT`ssG`ftI>z8J<~R9c7gQQO zfDh$b)W;C+6K*KhR&S+hlRoh`t%%!KldEOvL7svfLCWLDiB2F@w=21NSii#~_dV$R zO*TC5VaV`v3G%l6Vp&op3Pxw@`sOBebf)7NjPwZb=vw0vtRJE!Q8zNn5kx1`8)2x` z;HY*ijWBtL4+n*}DvLge1IRb$_EDd4iCrCSJxbPA+N#R@(PEQFsK$kceSL2J)0OU` zx%z3T?@-t8lJ~4XX2oKH zIQZ<8uDDezW8^;=xlxxkS(g;X8lk?CHZ+n!P3_M za@Y+@4@)gGDlX{2eLXYu3pK(=Lot5?k9fsQd-&c`PPtXJ zAQl2$juX8%fau@>GuGxT<}RD*yhc?{7K8*WZG0NJ!i|OEQ023WCg1UGpUS-2{s!vF zQ$xi`+*YvPv2z9JkwNlW+?yHKp_1l*?s}IhIMnKi&Q6)xule9Dobl!BJH-A6tq^c) zaDSF6Y&Ip#wJUa1At!z}KGK0y zLGPAOiYEATLsP^Uv}@GzrZn$K@w2Be67ym0Yp~SJpN2DkVZNoL;$WYPyUmVc?O9EX zhv|zfIwc2&G-sBeaOw-Zcsqv{%^*I9AoJZR@E=VDb;88vDPgDt3r;IMtPzpn!9F5~ z0~AHvrw4>win}DRN7tu{({u(72wIPFuFy7e~W(dKpoHH-_1uUwRh|$vp3G&P!Wr}uFuQ3q&$K&+x@m;1zKOt z`@_Qj=%HvR0_-q`+|nwGt4t%+=MI+K#;%%rBI=G{zCJGd*%_?yz`5Ps^b$W-l3+Re zMLdGZF6PNtQ#q6dyNGUN=>hA)VfH6Il%t{j-(}@xm$DS3RQj)gB?15;?grZUvUDQb zP*Gx#`pu0CcAah%!94^nn1gL{MINUp6i%!v0Hs}Kzj_J@I}lNz@akOm z%JIYjFGycln!K>IELn*y?)gcTRd{{b67FN>kdD8h413{P5rO=)yf*R{$1&H4tp*sU zcUq1fY?j7zyZ{%IH1`d=#IMSyX!Hmh9H$1!-w>(%l-geBMjXM@<-;UuLi3CI;#65L zOxns_LjZi``GhD=1<$i(glt~p+4~3Ee1U1oq=*`s`&y6>%Y$&`BU10KBblV&At^?^kcYXy}vmQ!pBl7a2i}a+GhSCWATygb`== zK?vQr~n*@lO16 zXLXa1YOr`N2)b5KGx>kZ79PQ7Wbo1b?pW8V5sVl<-Dty9g-=J5)VSP($5RSpguVFb zh~i-m`_^s^pXV9jDWGS3l5yn(JzGu?KdH$4v8%kOClMX|z$i0!({2Kv}`Q1xUutCENj{ z-+lH$=!VfUwR;CBKZn*XF^JrbhFEiIEX1;%+@Q0+Vgi{~$O>(E)Wr&_uqC5L20j_# zUbLO;HL@JwYufmnGzTdAuF{qyk8FGc|0ioDMDL+PS^~dfkM+;XZHciv<>rlnq8$*y z8#DDNy*A+QzxS>)t=c;IW|vkQ*t(waDsS|^SlfPmfx|Hq7r(6MU3W$mkUyz z6c4<%@9fzkyS9&=2kajNB~~&D%7qx&m6%g2T@hYkz1t;{L8JCQdoDZpJ^c$yZf(p6 zg3%+qyuw!i#N9~7*t3dJynmV?uk07xVg45EojrQynSQjJW*OZ$W2ngr+&3ZUVPsi; zn&L%!DXk8;?j0g|9zWi%XZM!sHTV&(mL)|@ju)cB6`Eg8<^Ekv%Q}_uwc(bD@?u)H z>^nsuZ`5R?(14Nx>%RxZMcYt5xmvA(kWI9I;2!pLEn#kHW@A}&a;dNE7DR75%wz$Gy z&xKkpTh?qLbk;mzY0P&4VmBo1yHS|YmjpY6nd;Os`v-QB%CRmF>A3)|!7}B8_OWNg zQ2l?(Xff_Ya55~(f9rD|LBW=r<76cQ?+y_OnxERf6Iu%rs1BkK)HhRlW^a2()(6W% zl|>##$(XzIl8%b(5lbGOOnq$6g@T1fa2 zTz#~*X+7tI>RXE|7cHSbNwZL2VVZ#;f>dB#AuuJ2VI7!h**S4Q)+#l*<$omm=pj! zBeNf}ydPiAvcS=_kXC;6r=Q}i?Q|E)M<1C~L+Y=&0ZZ|YK&dn2W5ESjZ7_RQJYgHY zDHJ*pmxhviXGH-}$D>k_0q7wETsR)3!5$e&xXUJO`sH3Cfsu_tab0D1WO?1trm${p z=>@R%mn9yP--XWt(T(gfx!C!yyL;ULt0Jo51-v6PWCuf>O@Hs3rR1}C(2a5ZZY1e) zk&Yp;Wq3#LaN9+(i60e4@ulGfzjQX0DLD`x(YrgXjDz6y$gQwp328Z31?#p756S8yZZ25ZZU|RqIJF zgNp+`gX5G|`mZd2YXf;2(azN7p_*vx7!fZ35LhB=O85GDQ&Y^Pi)U<@$JJ)PUeVjW zDS+>5UjoZia82cZu!*g-5Ns&|m3DR8{epU=RD~F6wyzd#GG?rD>=(xUi6-ribw8?B z858W@y2&0v*HxU`b%xu?poD@eW|Q@Vhz-pOgO2G<{@ot*k|hL4i5yYH#2Hb7*KY4? z*=25n8}5ZcwQmaAQeP`x5*BNu{F}@ix3+HJ4T6LkFsKU2-^dO5H&PQ8`)(rHNi-qM zp;(;RT;MU2f?X&Jz}JTA0P!vvZrNAB-OBx(t+Hu`sX}36??>=yzDcgDcGa~1dTi{s z8xX00Ab}&LZI+cijcO0b-caWSIL zbZhb<1I{_mx{w{@U^p%!BDvwREi;A!&oN@_0pvD|r0y`4Tlhd}fqA!rL0+#Ap!0k8 zpLd?GXH4jrL3KaDiSr+;gK+CjkGR%`i^@3AHnsrO*KA|=rVMBL2_+sb%JbICov=JC^ z5>UqtsuE@^y8d=P(KPJ$Jei3P22%|;3c?WJuh?%8|75S@&f^vGCS;0vN6fQKA$rwP z;F}F7Ef+=0`S@C{QX|yv`E$ExJBw8B(oD3^fIt(m<;NvP%6CH3-=yT%$XL!EM5`yx znvjvh?nFPHV7)iHeve{$c~@Vfjba_k%I;;>T^#$#!-8Si<1egueCL+6nsw4~roam>9&4a$@%lYSK=0Q$vt9fH{x-8N;%}o$wOqG`-pFDJZno zkM!9d=^;w(@s)xwFaoTueqFk#fkAwUG}M;|qs-(^F-)OJ8V)vGO~W;48e2)+GTVqN zL3^WSUV7ldrC$%>1QvPyorkJnQR~lU;h|D8o1Fjoc+G5lTukojvRXBV&*vg%_McHLqeR zYk_Hw@j=O}o|dyvPM{h{u>89~SC57oS-Ozn5%%j1xcB|~eSOAng}IfOG{H$q;y z44Qb9e4UfXf;O!jANX)Xu;LY)ez*Qd)Y4)w;stHP7e?s@V*ff6l<$~B%=0z?K|sF0 z9sA6~jkm6XD<0S?6y#drBttSVR=-t2URtGH>-A4>?R7gpAY?NLxg~UMA%B4Lskx&i zBPaC%XmhpE2tU1@UR#!UU@*l2>myDPr%|ZCd%lzKQ<$-q5tWBxywZPFTz;wW{_Wg( z{zTh@(M0ME*dXq|RPaoB0F+=l$I@K(dvYhONqIpZ*Z7SQ~-eS34ebRgLn*aYQv z0eSJ3o&L&9`y162|859h`>ZO>fQk`gAGO=ZY6N0zuun$YQHbqxvMmHTaEZy~>OMo7 z?dhw`^-F6fz-x8%B+Bnn{l%<5o79sfmmn2bsDh<|)Pbx?W3F(LNCz|6&DTRS4SI@A z90rMr3re!kLklpQ>oCnD${Z?73Gp3Bo-Z(UU_b_?nS(~>=AMf)SOEx@Tgtr&w^r@N zM+i}Uu6BrqW?Gp=(<^-ypJe+e428p?oUUtjuB|hex`n$2gCgQ=MW9U{=&8m5HU!P7ud>9wJx}D1{1yIIZ8&u> z&XiD$&R%5)E4hMD>QV|bWY?Y9F+u2{?5m6ih#N*BPO1 zk)K{`qC*+S(2#~b0rutstg)hAz@{5hnezyDLm8N5a%V67Xy?V*zN=1aL!L?8>c|;n z&;hsE*LP9&A9WgS+|K!SaL` ztH%QzpzHjR%9?I)esLM&HB_~{UC?u$>OzS9&%(geZQ20VA&tC!O#U!}C-oQHH7!Kj zjJvC3U)xoLoDdf@d{vk2`RmCJ}JO5d0k?DyF|gZHNq^Oy}eMPy6h{+PQQCe5~`W5%d#3TfZgT$V8fj>rzGW@e-;yqx3aPRnG26Vg{BAng4P7nEm=FL z4wiou9?W)@;%bJ(O?f1I-O~k>RhRBasJq3@{bjTS$fCuqTk`IHIwG~3&!Wr_`%jL7 zn>zIC>u@XBAGa<_s@XOJ)jgeU*?aqvF}u%nT)_4+JUFva+*La_QRU;NcYg$L3~P%u zeYWyeIBs3zU31m^55aZdNO7$1hHf&_AzFH04K3C&N6FaZWY2<~sAcS=CjSO!X439* zN{7MShMd9-PpjoTL|p031YUbkK+A1Dx)yjLsUx99&OprfQOds4$3JgbO3o>83Y{cr0+xXB)&-{h}Lf@8KBSCEx!=+^1d}tjRrqp{o;Z}fFo zw^Yj*1%ZR%Us1^Q$?R+r9&+elEh1;@SBdX+9kjiTw`Sa#d*icZcO_;A!YS0DUoWoY z+Z|SjlHK3Mf{6yL=ZVUaqTIIK#^blOTSzldX=ap-og!f__BFSpz5$7#2h$4T*c<^W z^)^`AeDVQ&dr_p>=MbLi2#P1;kh}6}VX2n$8Ys7{v+!JhSDu*Fb)u@!7;sSzson}( z=%}ht=9%?p23Ru))M*m$Fj{|mb;bS`ImUINJk4+^)HI2bqu4_JKVFX_z=T!Gf-KDU z{7}^%gND%X5n7b z?dwzPT6HCN{diZ#sHtF%H{u|+P^3Nr4t{x*Xj5aBYA_yt<4jcDYXfm#tg`h42zyPQ0_Hgt(uGOOXoXvob@UV~d_ zto=v6uODDbwvFc7>2xEdUf72;R}JYZWtzM#Mq&oG{zg|Z(mB9*ug`h4Yh*GHN;Xq* zQX?Ojuw`{k>C`7sY{=Q6{YKL%RDc*;nKEi=tT#_aQCVg!7H(s7E!|WHIWF1k-zi9s`UEkVKYUGq)3F}DTvd-%|= zCbHL%yZpNiiAs}Z*%!e)bhg5h%Y25SL>^t6CdgpmU!aF+`nM(p&5}~*I+SWb^3^RW z(s3xbhw1JF@Vr(sqZU+sk1eQlTEU!^5C;dFDSzCxJL$Yiir%_=G#&c6@zp;yT2*~< z|C?HLoiu^oew3!C=ft^XWG5avyDt`+tKa}354)vh@6&SvpM(HWJis_+SgWR|$` zt6;z)`Sj;p5IM;(fh?S!Y0VireC;{fIHW|7LG#*DrWTh#6+my+! zmgxo6=qf<{kZU{Ix}}Si;bN+)Mp(venr9AA>=qcKt>8A?y!Q``1_TE{sh-EKE z41dSV1Sqi*)ZMT(9*)YJeaj9w3#0*RgbYQG*QfaP;oEWg7|m6kBByEJ34^!Ucak6~ z{R}_2GO+hP4N|A_%Nu0i19K=6?wyv9UFa3)hyjzOmF;VC13 zL3w84RF8;*Jf#pP5`#6Ms;D5G$;e52_qk3bee2BXnvSEBILRJiZ)+llpXm<0?4#uZT^LOK1B1k&2~sh)5SgAP;)r8vyB64Mi~p@H}Hu&{A2HEEhW#M z_IbOdUb=dM1KFvkt)Bf8T zxKCyQ?N{BiK5|W!rp{rVe&n(k zKsOSH*+7*L#PB}DOB&P#j9;}8@u@aW%~w87MHONU-`Z_XCcN3+s|WZkMeLRD25By1 zQWpA+NBvInEfJq8C&ux2E^$|cB!0#U7ZVinI}V)12};Z(53;0xSKQ~-p4!u+bk5Cj z+-9Wra=?%ET>bC1nR2`{>EJUw?X8ujF^NfCLrJ6803)_-%Rp#^wl(XQjD=;4*^o&Q z<1L0;sIo3k78-aHx|MTca6FZ4>s^BA|0L=^L?uFWY-{F5sb2_5qTF3FWxc6%Y|**W zw&B`Uz^2-1BHgpU^_$#MBkui2yYo-sFwOlgq~;HguvP>gruhM#71c<576S})hopP1 zBeZo*>#YH6R0@dWjgp7zj{QVXGr=6%&IzN3fhK}I=A0e=4Cp(1b-VJgW4vo7CiMg5 zX%fZuKbl{>Mo_wXW1HFmrgg5o2YcwwR6eNrhCL>F?p8fFK?y0?LST;{7K0QgA~kjn zgdD7hBk5=|Ad)fNpG89SQ(9eKY?m!+c0}`)zlf+r?-5~pY#U?oHnTIEQkf72>Q|`n zOaO4robLH4Z=WQ9GN8e$FG_FPlLldh5=j`}t7XmO(>)};j#CpQYKU58Ef_bG8ujVU zrfoE{@}qsXclWS^^x^VNGRyC(RnvH4FD7M%p8f-Oz9{w`)cU@HMR1!{KYN4oA}XP` z9es>rT?9SQaK@ND@VuQ~Q<8%(y~UT%*x4fvM%>4F`h zY1v5U;I@bH{;4}nbs-zaU1VxOtuY;k& z9qTRjgj1^Sg3{#0ERh5eUi0nQ^~E+S^VEKXcu2;WZ`az!f>Qm(B@lCRu8zYtk-Wzp zS)d`L*JyG%l`}%rA-8o%jp)U;OuMQB;DXZ}_{5~o{FWtg63$acu@8?}Oty{3(t6K& zxUG*==em-EDv6w>gFA=C=L`eodrx-34a zY{$Pv>}dH2X8#^JcEh;Asr0f^jHTbO>5Y5}F7I8-<>H%wr#T28T>JC0{v?q|Ck@_4 zSdFqtWIMnsw@{|Jv4L+|)llDR$6V5*(*nRz(Zi6iXZg}>0ed>uipJ#sP;cOlgip6U zqKid%y^+AoIgoJYFCJi$#l9T>I*Ox&^|odhd%BGa*!AVsMB>@wX=CHf8~xKq^Lm$u zek4uYW|#Ve6@i~L$LJ+N25tP@m=lWQ3b|TC92<*5+Rt=DQ*Dyzw9@TK^FE2j2IdR=~GW-(}P1VLpu-;h~dq{CfTFMck>pf z#4k{IS(F1jA;%zZrJOk;c$1m~0+fm94t6onC(X2NyTgi|2HMLCK!=JG;lW~|6V+$w zoGbxe50%XW7(hOSw&o3FTt;m_-M^2T@(6b^hLy=mH|K}Db`EnCS5m2*oW@B!3+42{ zkvz7Z(xLIC{$c+**V+BE9G{HS*=pWa$V#gsouz=0P69XCO880cCW5p`%17~y(J)IA z(zEQi*r9z_2G@Uarn&>vsXH>&CbxD`^gk1H+n(g{Rzwk5*~)v9Q10PgjC%g<9w>G7 zp3rLt$~hk7m}57Ojme2E5&dhd?pg)5+vr$({~-}L{0b#q&*rW{z4h@qj)ewngM77Y z4d+pMt9vD*KX^)UTsEZm@ftcD4@(jaD7bo&Vm{Y#fDb=Y1SVPd}YvC$pb(j*#0k^3L z_P^D7GHOUX2=WNE*Jjd)*JZUkK|?aF8$#U~>H1{zUVaf;L?<%=jaIGA1tJ&0JXdxm z4A4lt`9ts?-6`M`$w@G%8Bkj2tcz{pLl}>vG6ZT;6MXR8d$Y?ioC`l!mnhe#f?UOY z&OG*lG_i{@VSj|m42s3TX2E-Yv7N-=s<_~5Tz6xBYEhD1o&S~tfeze^Wv&_pBCI`( z_VWuDLC8kP>xiRT)0V8o>$S)R<6WTSJzlZ7St7QeMIT>)@@Eo_YlqN@m&u(#CLADc zvpD(^3Ef9iH(3rNN-oh*;pXINX*%8% zUWak3jfijIs@tG2;Gf);h2ZOVJ`C+6)7CQ_$3BmkjXChnH(PW=`mu?IsV(S4+^wGeS@@@`NbWiL z{`1I_H$Y`PDx_MS-?>JOr`kPaCqaj0SWdU&43>X)p3sCl>>eY=|;SX?o`0i{Yt8 z6tEZ*%QD#jr&`P+3BC!5ZskRG0BvkdrJy*Ez)CLd?4u$lMNvzv7$M{v?y!f zTbGqdWekw_az8|b#^I|qi?HaQ(px_s=q%YRE#usOM!O^Ky}j_62e6p{KsSL9o3f6h z4n*uaNQCgzx8xMNb@s@SH+H=D?ilH$6>YH`!$m(Ti{)PK%iC?a^R`}I+DiAxEo2k( zZj2g~LhaZ&8G2lKSwm{i3N~p3>FJR8>SYk*)vdf+_RCiBA#MK#4a+buy)47z^0>CU zdQSaWrO3n{8SD+0EKt^Zx9B>m>hk6U<(Z2GV#}JMC`~{M`hX(N7Mrl|Rvox>fw<|G ze_rhBwhUQL2U5aI<+CC;XlVAaWt`vbAE6?En@|%c(A5*?qBSb5b|{URY|%IHBeltOF~O}DNoDC z5DYmQ{seCg7{ziBy?I!ZC@3M0A=!`QV5!Al1_S7yTRK%!z><-1KAMIob)*Q)QQRmE zeF7-HSI@57a;;uF_}zZje4 zvq%S&YrRV-h?b7F+y~O#A#W;FsNt~JSVvjZr3xs$0rAkJX&nPqo&{-v6Tt2Y>kaPW z54d>cE6KKV`xeaRniMX)L*6bo0E9Xa(SvK77RBp9{de9 zgEfJY*(_{JkM{%{Ajyq0?OJY0R6)#(*WKovrv?9hCnW}gvk9IyMd*n zN+et|0OYW>n^03+8RJ2DE0#jcR(Q~WOx7;j2w{rDTJQ|>C_~~XWhXQ3@kKg^!L*4s zDw)SAapVvPW?Gpz&S=U%&lzU;M5vkoc~(@>)TJdMNa#;1HYC`9(I}l0c$iy^_I|C5 zUo;$d&$RRQqy{ndE(Q$XV4EgXJ$y^Prqi9+% zpRn1EfRwF?i(XB1lqvHm`LV}@qkNOZH{$4!Pq;87nFx<`6mU*FGyq<5&U(=9{Cq(_ z2unz7E8uqL&7l_eb+(ZYq1KKCJfZeNMAOVZC9Xe_=4x?3pS%N>P1da>Ipj`d#*?H< zC=#SnoKUoHswY?$msR78C;WM~k^^$FN=!V_uB8U~XBgKE`4cWOban9&O6m;w}>adK% zClKhT)4I#D4x^7dyNPK83YPt*c}jG@krMBjZEJ!SITKmTPz!hW?J1j8s}Akfp_{f! zz_d3a-;uM%3NYUnFO-0UQ9JoN7p_&341Q&iyLFW+ksg7H&>L{c;pe3dM4e-+=>cLk zHPHGs5S<8%A>=){+wF`@0sKLl>g4Q?dQJGEL_I0t4NHl~Bt5!Z6LBukrP5M> z1e-`L;rjTZ?Ww#Wk~>ykr>9VayrGYx($hD`{so`^>N&x)v!8c6fmDmq3F zQu;|VeLaWC1)D+C)|Fnf6cz0&*+VLmmf%+h&OH3*QdcCkg%UR^v~Eo9=!$eZYAXsO zUoGCn%lxZV?tIHeVov`D@i7?hCrrJD4dmxR?rLs#poW8Y1|kXR)f%OU99ajq1_nDJ z2niX+n2bza_U{@b{QLel8mKMT4^vFeI4ut8LIk;s`7ACy>nYtv`SbT|lzrhSP6n7U ziCxQ!!@CW7#fB-?^?_^l)WTnSd;1}HhBCV_1&%2aD!8>2*m+fa%K#eR?u`$V!G8!5 z6kw2txlVjUt-{njp$%__X=y{%RhyCc1?N216!`7!lg0+_7JWvYV)95Fw~HY3%JOXx zT|5oTxgtinY3w@MBOpw}TM-v=ia@JIR@JCbiUkqHY7Bau1vSa0W$Qa)vN}qD4NT#mt$+?C)85f;4Abo%Dozu zmK-W4Q9!cTAw>`Wz5p!@GLkBs4K~IVS+uS4)8F6G_#qp>2S|%7R9vEO_w5>O(_;O9 zZar(Ms{MFx{DEzdnaq!*wDFit(X5$@LR(+U;F~AYp!?{+2_qynDqrdNFnH@u`6rcR zL(1dN1tZN9l^r5iaX+cFi@uTErJQSLX=Gb%$;vhC5%~26)LR7UFn45an$t2~U)T-a z3#846cjRRKaOr!Zoq;SZWlLSZUm`)SvUp(_J$Fd~tg3VFY22ND6aA5g-Ba?wR+ zH;uEm87TfMXkckKIeAwi#^wY+m3?b=DNB()OBM^i8CXV^8+Dq1wK!6tcy>gAPT|1k3obe951=O& zPfj2BUD zq`~f3XR{Wwe6K$KwA{|Q(7Kxxpy)9shM0&fLQ>fLAZEN%MiyaPK-^H+aIW2~Y2FkN z0kbuSo(0cL~&>7cY5mvFEC#V-OJ9QiHg!m7$L1jMrhJ62de#?FuF4 z_eoz}^3bm(5myHBvWYDIurMU19VBf7P9fSu0{aoJ>nH<(H4sVEwkO&{JJ!lP%lSKSZ=OcL|M|$11ea|w9cevbr<8b%`}0zaIZ1~ ze`CK&+sJ7-&jX`7dE@V%5zN-(Hyux=;o31W9MsNL`NGdmk7qT#-L--BvxFc`?Df)J zh}e3KSnaC)WojqFNy<*~dhRKSF%cPYy`fVg=cYPT=!~JQg)9LkjPFF~V!wgywt)<0^_5z)gI(Fd%PxFM_D?gbHrV?-^^NexVL<4M{eKasATXhaJI!y;>ncAV?=sQ7QCX-W0|^b+>f0OGkvw z_SfUZNK-tl6>q+5caL^k7w}_zXM%L)CNjsvA^$k%XR^KW>JBw|tiL7`T~sK&4wGQd zM`TcXS90A$BM%hi6qASZZ?XLMAx~@vWM*taRE*2hl`H)3!TT(1K>5z{L>EA*(*t!wo9Xhyq6xw!!}9<4ia+$`(9rRt-%shP^QD3yk_OnE&=Hkp)?80`jz~Wbu%n6}NY^xXd;f^Mw zbPS0(If+N|2LXUZmJbwt5zRd@0zZ&GNsPH9RY7ZG!RS)p*}p61LoGEsrkQsXj_kbb zNxLKN>mBpY4FHpwFeufK3O$8^^cVO?fVf0Y>Dj6!kwmCf<-NJxK^#8fLTyJUG!FDm z#H?>4j-#H7Nz%!L+p=W#IO0lgcNC6+@{{F0f0s#) zUqAVlz?B%m+!Ir?q4jw%3a9AEy;UqGAi$nl6BpQ%P|x`ZbHh*#zgn_>y-t>189Nif*tSWpwocj*AdpC$hh9C9Vt~x@4() zecH6g%HJJDfnk3 zhPV#ZAUESUM90T1S*9*hNv#>RYE9%i3Q>`OirV0gH=t7{=OQ~ z#V^Kos_)h&)mC^iC8QW%4I8&ocMU1WXQ0iBo(a;`mVX zZ(0)onq8NvANY^^O<8?}i*8wgw2-^XC@PR(N3q3(Hb}=lIRS=9Z(Bf0sy<#)PBGJj zq~hMwC49k<-h7Qe7vEcVJ=9SSv&Wd;vqm77iCY4sI3-TkS@nnVTWSwh3cLtwekrvB zdxPoF^|;pq*8)&pshXk?4XA)KQM4EVrat|;&Q43Whe}gn{lJh?^&5+AUq+xiyT8^{hty4FIFevN$&^5L>{Y|WQ6~{!IB}`WdbnNZHyC*i0*qZIgWD6snz=06 z$T%Q=wW4muIQ|TSe(c)E^WEV!;6th^uRXPqH+JE7edt7)CiVw68EogQIj8P^dqqKZ zR>>o?2}8;#1^dUnG-MY6%h97m2Kxa{>0avgFBg*u`(+oqS7;oj8i6(okBa6&?HnTr z#kk(k9o&V$jNll_aR6A^gG3&>CIr3=hqbj%M%Z za4Z3NL$GC%x+|oBYTsik;(QoBs=g7>2>+4#IGnQ03|in3Z&cxjkD%kF z)lyRzT~3iwC1+8iAavg#stx-eEN`3&jgr9g+Tc}ed@B0(+BlgSlZ_6f4n7! zo=jatlr3YL{jwq^L`qcUVwLGl6__Y!)&}yBF~%J?(d)rr_eD@G3!@sBr%){5P*=F4 zn>!u}mli+82{`GVK&X)f*Nk0jl{(AD!CajB?@SKIl6{hNm{B?+B@C* zKjLx-fzG||<#e4;*;+GwVaujX5Y>FPx)x95P;@2N&XV#7tj{YAR^ICyM#^Mw1w`&T zSv|jlz3!s}xl^@#bwYve@~FI$sVIXd+|Pv|TOc%5k44hnP4*J=zUiScS~%|GhmyhN z@R~Xm9&weN^USfZ<1i_ROPBh+NMi3o=Q6>Vgpl8Pc%N$^9KlM-OtmO6!D8Kwj5fvK zT}lJcxb;*a~SXuUBsx)+#=~D@4v92QM*rMY%M&etP9;2k%jkfSVPI7KFt|b_96i zI(Tp4MRih(8UKX=HK$^O->Yk{VhgTpIwsmk?tso-b31IYgao!G=)I%V`$ja&uYN*` z1Cfj7M|qX(H%O! zir#JGr0nd0&eKX zL$tVeTR_ZgqIwPag{$XTrf3IEU@I20CDV2KYmwEir`lJCw8;^eX|za`K5 zL_RDuZ7U^X`OT;j96Bem{%l*;A3B`aTZ)dm$Km8Rcc%+^=R&%@|J+#uff_F9sq&8# z_l=n-+v-&3aF4Y#6(C+?0uB3iMS*=+H~v0fm&wj?w8LtcTg^TW_Ji#FYkz^uLYnkk z#NMO`C(itJP?m*C6bX5ArBEOi@{qmxvMAv-?YlfLK@Sc^0`OS(!aPh5h2%B;(-od%z~QOZ0!vO()!)vO_# zM#mZs&WUwvDjc&4a=W5aDo*%O)Z zt#pK-1${`je{uY>BEMXZyLT`BriTK=fL2p}NXSX3S`7`E9&>wV=4Lxg0#RR&ndR_V*M;L{K23dDbHV8J|$?l`q18Bu$SCb zfA7~bi!iY}ci$+m1Rt6>Lo9!ohHoW44tdx2)sAZjSNlL1U<6m)B0Wh$EW$^q6~(WR zPrfm@st@gLA~RlCE0j6;PQuf`nh0xOGm>a7tXLW2M*IOb;=zT*f)`p?q&Q3e!h-1= z5(hY^rl&r>Kr1;1zS~&x@fL!5rH#XG=5Z$%LkS_i9k_MZdybxbWmkk1I_(G%`Vur& z-~*<$Q9<{@>;_K4M{S-jB40N^A?0+!hWKu&K$4aKs-god`F8RHCw-WhOtz5gGLY3} zK)Lz?N|(=bHBaDpCMI?gA*y$BDEk2$HJEfYr@-goDjbei+*;4;Z!(n`vJfchqo!;uoXRARH5KgV|CF6 zP4x*}LocPgLByfI-B|S-!tBD68`54GGfMkY>q^WGqOoT#_hZt=)nAIvTIP^}asO4s zR$v#oFPIcn*sKs_B$5C~$PFv^Rf|J8_6yQxCGg8c7xiXL-zic*Xlx(aOZdQz25=>P zdZk?*oyE1VGNPw8y2$%2K5~(sDlM)V&@4($A>0wR;C|)ONeXvcy|O&|T+&p5r%xWp5&OBDf*E<6 zcXA&Ah|0vE{{XFC$Im$-zUaQk=`!B4?&^w(gO4r&hJ_k%k859G+D6h5l+NXu)-(1| zXM8XuTKZ5wsb0$Pi5eV==`6vZTk>zgx}5zlWrgQ596Y`UlL|PT9lhcmT5V40&Fib` zu0Z$;)vv2TW?*Dl!Wu~~wm%66@hhbO1>Wosg;hrhFtqZ&=p(3YWb1|Lh z(pz?#S!W|88{ZGmm!;c-UsWUuNUq+RNm)ptbg1s6E*g=7SYf1bf02@m4VtZI0uD2koWzoJcQ@e)TUS$ z2Gl~AAuR}xD^6|A(Xm{0L?~M3{L8v5SRG+W9^8+RkH`_+%>sR4-}tmeNimGwm83MZ z^G&mO!wFDV9=FZ*41ZYITV;j%KO-T(5X=ekxQs=YCZUxKfueuoT+oj|xxn9=|B&YOp}2k{tS)M%wU{UO%P8+dJl-&NFn}`5_-~A6Xs9cMVCwdys=!(R znGOCXf95{?4CeOZAuu|;W{t0|I|d8MW;|J$B{iL+9Un14$%R`epGf}4kEe>|_W&>) zz;@7ZR2vnrwqBrelCp8BwKPOGD*#1=^I8m$PW~wLA=hFkWv2iDv9=I9e}&WRqFf+d zAD%iq-*it(j0pNx0?E`n5i{-wdEhTfx!|%+dc92ey2}_{KZ-Wo<=Vmk;u^NT_L~od zVa5kxLa!0!XAH;qK=o9Pj?T_k2&Dcxy@)h%jSubSsd#+);g^=aMMFwA`r=a$XqiCC z)~U~l6vC4rF~r1=a8@Q>Rp+)%D8AzI0wx-6imm(S`ovps&WC7$VTQ(>+wV?2hb_wNfZ74WQB{eV0djNYhvFg)67QK^_bhzk)8*_G(m8 zgR%X^hBc^z6H7=8>gKSLtjV#$A?MeKs1jSEe6m`;cGpahoLPjJK1}42O`#((HSb7V zcIt@vW7WAZ7ke)eFHfX2E+uF>bh|O2LA|KgCqNgi(iRK%GFp8|_Lq({>xyKhK95k6 zQ5_Gb776{fF65;U)JjQm9mmE^7CZuk4lPFX9)SF&NQzq&t1+NjBE1$UVi5JRi6{fU zDTOspV{7~)r40N2XG1;>0VwYJePu>^LeDw=_ zH#fq2&lW<&55VmSbKVVb`h#%%T(ph9-U~dU2j0@K%F!^MsSAu33fd%EilG@48q3((34OGayG-xX3h{>2 zzd#9bJ7*vmKz`Bn>E%Cv;aD#xwL6f)S!>xo;9`BPM6V=KFeVE&Yl=EuVNz-m@!p~@ zd$x;OdWdGjs#9p@I^z$DQ8l^grf?Mz1D8FY#yFV{U7y)&BodMjm zLQYy@TA34kt{_t{v@U5F&1k+tQGo@fy14)P^in>lkVN|SCt=)OijECyi5d;abcu6# z{H1A*GQj*@z3W*er19N7g(V}lUYWu;{+u8FdJh?m@NbZ0xZ1V#R(-*J)cn@BbhW>I z5o;NcUER1{y(T-5YcFvG#i&3gFeAx(LrxU8Fi|1RN;jo&iaA=C^7EO2LB~$W?qDhk zm2GekbG3dPLnso%uz3GuumFn$p&8_lLww|g05^gSCO0yS>Hl^pc{H2er*D))@&g|o zjo_D9T86xAbG`<4QCn?(;aVq?^tlWnd^*Ni7b!K4!?Er9Fsy$HlHBp}df1Xm>RcGT zs3Uc-7f|NbZV(oCIH3wx^s*Ft7Z=J7D;c$yV?^zXS7%W!7pDt@Glk7J7w(Ms!564I zozptUg9GS2)&;nBM=o_0oQ4JiAS%x3N6HzTs`GAI$wq*!Jr{Fh1EKvT-$48t7S4%a z67bfLt66s?wqWrlndsm}IvL2hw02)6!Gq9mUSFsdio-sgMcEh??vPFyEku#yw)mWO zO*8F^;i&SFxv;m&8`caB8jFsyAr4t?e!d0}QxTdKq9sG*QL=B@HZvwSi zeMmE6eSBoIABgmp_jm4WTAyg(+MF_+!*htt#;D&+F|fhRLzP>;Gh}IAq2jtQ_i(mn z?mWM~T?|DLhY=n`cMabGbvjqzWJW zVY^_yv<`v08|{By!8{HGYebvy&X|@^Txl;@*S2NvlzeHxFyn4JF3>No_XElq)UDW^ zYNJk*d1aNfUdbBN-EEFd#hVi+#j5z}t(}+>eA!6Ew#bcNT_n$8u2@PWOd*_pjUcY# zo2Z^&75@paWz*>#jDU90Ob@1B&yYmFY`#jM{hHAXg!Aa5``J{2z_WOZmCpZus4f7=$qepJ31)X&pr#Q zvA=6j>DJKI5?JszIF)nhnGBE;xR=fJK}u7rOY`!#&CZDz4oXt#Bvb>ln4*?)8QHr2 z^OcghPw2_ioGCMOq5c|v_t*7;Lc~8WPoxp*63FFZiX`=~o#GSeK! z?nsEvT!*uf-sIy`*M1XN(p1y$;|r^q_pMo#X@q&1WC?=!fn3ohs^)Plqi30-ubHL2 zL)yqZU#eW58)0z$Te$6?k6T(!MoC@2kNyT%WoxM|!c@X8O4gGHAVnc8y)i=8NhRn} z$1_8XR4Z^AKR{%dzu9dZXCZ;#fvqgpu-cC7`s50325sASemLoNlue?pZGZ`Mn-w2^ z96>s*PclrwbU_+q;D9)%TK$RJt6di0K4oiel*^(q@XO`C9|KZ(ufyk|64$nbsj`us z&>5T$lWaUVffYhOzD(IdbDSW&hzLGgOiY=qMkA_$73S*~xD8>4;%11bi6e*Ic172> ztoXBTD$a$y!FR4|XF}q>3G^iuTF8@o-;Agn$Y_jgNK`H5PjAw#!A|2d`vj0A)=6ky zZ*WNF)qJU6153&N;G==21d!{D;uNo6ZaoA!x;NhqUHdRzdn1lmY!Uh%O7vuVnHs;( zk5i4kLBXu@Wp78$8`FK0sAX}GJU3?CbWD0jxc|*4ebe* z#s*w;*K=yQIfC#Lt$e8h_XqHCQySZ?u@P>>U)3ucO?6sV2k(vME2OWdob;8M{ZKtK z+m7AN==YVH zJ-**lVyimqR(f(%QbSU~skvgA`Td|2?U=Nf6LR)?T|DFXRqhB=6A!Ande ziMCeAP~@l?eZph|a9pl~biJT;N(-rpf60tCR})BwNSi^vjAK9%>+=^y4I~0Xi>D#r zOI~#N^8Oq*wARx6G`|9@mtU3PWK>3V_9r-^_8!1HwBZyfcaE-ZGJevCXwLq0jS(S8 z?GVwNTf}4jAJtF-z(ka#h0d188zXIc3Brf0`=N{1=5fUoVK6KjtT_YUA_ z7PD6Km|PtgYnLMChI#g-GC^Emy!8rBc)5i;s?0n_C?7`c!?1cHLV=Ri1saNOe5{5c ziV?FEi=d=Ud1%|I2f=Y%Kb8s#rt6n89$1y3SsE-fGc!6CTUTXDB`>%VyhLAGaiIZR zhY0qgCD_>F6F;}(C0HE#lQSe|y4TNcE^3n^UW=x7@Ba}dEc=3J|GF*ysK4x$Urp?M zpG*%xeyR;)&`~iaKHNEfUQtxDz8=qoT(0*K%BHL>$Aq~g2gjuIg~4+qN;uEW!T|4F z@4^CS-SMzJ?iYsoU;B8P_f zS(0utiE?@oV5yv2s^CQpykwDw9)yLP3@5l?^9RQEIKZjcE{;Uesp9u(T}jf2aFyU$ z-wWr1LKD7(g~a#9`gC1Jw1a!js~sx-vtP2hQ#6OHHz1vs)w*|-3MUoyqm4b}8*usL zIU#99tj=(NkVIg?GRiv(Qq@4}h4Zqu1eU$>0=9DK^cC3IAH5BJKna&v^@0Y}Yz-Q^ zZBDNSqQJ|9(j36JmNB`|(SF4NC>@HSyzvUoK-j>J0TIQibuDx5^dja9rfbPMTImD} z1fh6wOQQQw5)-oIU#yqRr&~7E50uExLQiJ1F9$)+eZ*5Hy4$?z9-`b))nky(QcIg$ z-u3knqLUgc7!2yZ2w(&c76J)F6v}a@Iv2sho_>2Hnkm9>m67xN_n= z3y@oIi9vzAKIndm`uRKR>ux7=!OauRcsZGxirPcR;sQgAa6Ay({);&TWgZWI3h60f z4+tu_-Z@WgBIgglC^&*JTG^&VwuMhw@1ykZUlbB}*>tv*SrF$Zy!9j-1x!5nNDI=P z`?{}i>F$b9YxUYRuU5ZkuF>AGI*Lv6#oSt^%-+-78Ny6j5Q!O%c%D-J9n|iTKTb}> zGs^bCp`nxZj1(N%iAJ2_MGUlMRe8E40)n)COS--&K(aJ*I7{*Lpb;o(f)}IpYX&Zy zo5)+PA~w=j>Y~0f@;d{!QdY5zIIW-X$EbW8T8Szk%+J65C3##@kWLA6!<`CEL8u(U zydLuP)5c!USry5B%gF)n_eKa9*aZ#tClK~||C>sAIA$Izy^ZS@vjs8dit}nqB1^12 zTv@T4|0C3C#vh1i+_tpk{}C>&vbzE>W3dS8Lox1vb7&0m+9=HvL8@fk8!V1U&gM26 zDq!pMH9`7k2P~%+ybn9RabKFaP!KC!rUu|WHvw_l!hB&cjpzLD!`*zYr%<|^Etv5h zQC-5KwKp~RsX^J&ZtsMe7w0~GgM+?pw&S)WU{%=2MtSm-BL1}}U|LBUZ>UUrm0%Vg zAYytrl~@UJLfV_%a2=ivQmSGRLGbiF|{&0n42-2oNl~2A#L-;{Y&#M(@#e7@Pn2gVmBUu5Uc$ zTh)xEJ2RYotf~mLmX*f*{A;?B@BO+#ZF*G3JAKJ2uRwo0tUc@Q=0tCp~A;PA@(6R41xr zgpl)4W7CBmS62R2M|ZU;Z|`Z z;rYUGhNk`+D&n3hF6Ua|LUIducqP2jUV~^o=?DWlme-Nre{$c$PRX1AQgIIEgb=-}lzOqX*bOhmrMzF51m zl2A79h0E+^BIRt3Y+-N-s?G761iH%e9xsrXN^+VcL0|NSve=9zZaqU)JxwPVWojQO zG6Wq<2{NX$7bd5~UG#3)fs0P)I4*Y~-*hw+;3AA|bVv*~8)_WSoGMqEo1AaFO8h64 z@G!3{!vxXGtRVo!kJjbP;J(?7FH@>7^j^_snU^v}w|2jw6d2rV)U2)hOBM6(vI%Z< z@p_v(sbA7sAhJ2ssSW@2U0=*4hPeW4N5^%kBE)7*L|@zcg^q_J-?}Ds|Cp2>ktjEX zV;($^OkUcWfaAMR!Rn?PBKty>hMfjr@?7&AG+Jc{Cn^38ZM~Z3MCKdLLG*@(o@kQd z96DS@D(G?ltkvk%CLMr%+yD-Tjg^+(jLI|c6RjGTM4)i#MjMaR#;TSTapK~b@R4du z08v-`1CJDy5Hc5DcAbR{Ap#p5^<1;V)h5rqmGd}QnWOIMe*s7#DyojmJJ?)Q?oy<0V3Pa>e!W`kt=5(+B`q$5Mwjj|WvP}_xsQP$iKmm@c2=6UZ4rHL8tA@B1lY3$;rIB^Qf4Xv_t*+;hDrkE%X{zx{f35 zX78}L=fsFP0`Ll4ISLV9&x6w-vh%nBb+PtGO>TX)c1!h<5a>f;KDAu%>5D&`UXVZ? zUsI{(;}$SO9N=!|w`V|I64b2&CC8E?!^RmbDMcCiYD~nH*Oaxik@R zY_^=cFz^BTk?xFF2UFAs^k)P4Y1Z)(6@e12%g&Ee$O6x^$RDD1M%%BIg?GgFRmEV; zdP8U3Wr~eTOIWNRZ5&zCjov;i%|;(u@=U1vg>%5tUzl89s^1ox}PdH;x&K*%Be=mCaSUsSgq3h>JLbhGhS1;qmy*de({CONEfHWv6Lb@`()fi`J=u z&YYQi(s+y)E}(XG6#|y%p{zaOWPs0IgH>i2Ew*R)4J@F9?-eJdw#gTFSH@kyzoX5U zA#jdEAdFkW*SK7?akr6|UT&*XF0lQ->vH=Nq!(K86(B0+;7ff{YcX#%PQwYvuYR-@ zdI1lssm|q|y^1Q;Z=7rpnW6(Ui`fit`Aun-uu7)@`r9~Yj0Ze{`Vx$ZC@@Ro*6XHpa5T2-`l@%zPSJ(cFPL=3p|wyh!X72h2ww23Ra7 z>~dS-$GlB;biXEj<$Yp&q5O*CT#tjMhiXx5Uel>lSGob7DUZzKSm#cJYA7M@ieW744$&s&@&Q|F9y^wV|SgYho{7rlv zG$NnGucw{3;k*;qblGO9e4XUT;g^!`nK9Qzg1^l!l!m_PCj25_JN zWAFVmGnqBn^$VxWd->B%D>I|C5c_f&QMY46OZ zo@wJcM;#8S(i~I?^Zx8lw#s#erc6O&CVBUoNXgY6XI!!Nc3p=&LRm^ch)58e_Be56Xd`08!Tcp9jl~yy|ZA3Q0bTHpz zh;XlQ|5`cffnk*x&fB1A4Mp>rgaY(Iwh{WUYH0kN4*qZGW(s8NSyK+f5Qn{t=)yw z==k&4pCi2h-)VUw6&gN6?0GB*2AHvD<;js7?TSJy1WB98rkYc2`F4Ndbf!N!3S2om zq!zE9L-A`B#YGnN^;efr8y%3HyFreLgB6}z)Q~)5eX+#IwZ-kiyvf(7a)GPqBY6vD zlRIoSNVxjYZl6A!1Yq3;NmiRYJIFGlU`(_Yct&rl{|jF23m@?nBcMz$Q;3(VCKGhs z30F=RaCxZEOf=<(NSc)_X_?04lyxKnd(MO02;Ee3g$j{oIXonzdzB<0uiXJ~%f2&D`GiI7va4bZdFpWM2@UvBe{W0MidPw$C5T6Bx{E`xk|Y4j zNseyM^nr?C86D?I1=A9rkzj?SCWWIdq_5CZn#pndu16&RL@>z?LgdOrp+;((9vl#Nn5Ba?+ z{1Kdl(cbmb4e*F|84V|BZ?8r+GKoX6b-hlY3;-J_^zJq7$Eqc_=@2VgK*^JKBKaFG zt&5^nfAVYJlkj&miz}14;8hy8r009aTtpN&ML@Kwo2Ew>1x6o~A>x0M+>1|kb z9ngn1f=<=faqQ1~ED@b4s14QS&5o<~00U@Wd%!)s%99OmS-mN2TJs?RM;vIuG9J(5 zqJ+`TM?LWIIePgfg>e!wvEfE6{&SQ1m9SUp?B%)|L%bPqf45Pa(F7dyYgroF<-2~) z$Ly-eiQoxlLO1%4g4~YGcd*e;xK6yuQFq*Je4YcHxEk3zH-4K3441du(rlLgOzeU3wbFMog? z+!G`MF`;4Q#F${t{f$)S^?C4V10%C?L|XTRv@Cpmf?1NnWGt-l@D5x4qchKx;o2a9 zN$qrf=EX%>4E|a6u*&uW9CRTO`oQFTiHe$m?|BTZpGJ(F)d!*RzfMAyQ+|2wSnLVF zXNKU@sWft)@k+^iMZPF};~U^&2CQc{e}ji%mBmn0_Epj$E1Mq1&MxQ4g@bk)$h~#L zt+Reo-PZ-1Q23~j5G7&WA{H83+-ws(ldpQ`bPc@s;1%j;XJl@$bhXGFmS&Vs#-PCl zqhB=j9{Tcu`vGI1QB5o;&XaL1weh6M`cQJ2Pl1p()=Is4XyJ^#c?%Dn5#;7SzcxF} z0r3la(#Loc@QKs=yL zNiV9t@55c_Ju$X=Nx5VqdySDSr=81(w{fN!%$vMRiEvcaj#el}f49i4Jy@Q-<6!}# z*_sOwxMvS}>PrP;vl?CuC=qH7x)QOVI^tvsO7!9~CKFl#E%Y3iKF)(%LuqYca z&zWfq#D4EuT*pSf{M_X26Btqj)(AOiS-O$n{Ufw@585AsLn-6L;LpeRA$@v66Z%DR z5R`<^Tq&vUeN^;ni8iiZ;m^<^NZpcTR7}UQXn105go#}d@g%?2wXXW%)Tomx3eAS? z63sl1OJ86#otV@2o0Wen7Qi0JnA|BS#eDr0sb-Aki&Z9;BDb>F7gX~D$9$~kMLTuw z2Pz$YwJ#%&|6fcd_WR4?X!O10E&p>N=?HxR%$fH-s(Tc33(P_vc)l1|$K{O4^iB>0 zGl)DBRVGye4;hIx%}8mbxWch1+yl1fJq28hnL^A-^O)w+%Sw2;5u{0PTryxw$0Cpi zO1dhNaT<r$C*s=|N%H2sH!xtr~lvdspA*td8h-vXGL7sMufn8}e@+c$Esi5iA=Af1(eqCk2 zS9u+#_jrK}kwIrOV8f_eCLWdTE#}ZMKnSfIZw+gj#gy!TsOZNSvnJ!ug-8o3^e%u3 z_jOx?MU=EByiwDFhpnu3(w}BThFXiHrSoeicOS5E(rq`404|OH$OARWxb0?6zF?RQ zQL+IJ{_HCzjvI7aM35Fs0EN+3+yaAKuH%k0ha0$bIbLX0Cq`7J@*YVvJsgA3Pt9@z zkMXE`)uag+dO5sA_G3=W`N|PO=u+Ubzyga&Q{vm<)(u|k;%`FppIC^TP8B{lyequJ z9N^9$bHb<8&xKA|uxP@BPj$mFeczLCi8`u3$$_E!=JH71b3AK2JUk9no!CfvI=%5{ ziR3h)TDj;0ix#g9SL3Sq8Atq>Na*~S$lcd85o@p^2#vVY^0tzT<&_ASW@dA`ARoyj zZA}(Mm|}U`S@A4T0RO~fWij;yS?p~zztoa?)IETHSEPMwSIlx-7}VUI0|3>g5Md?K zn`)C^G33SA19)G2BQr)~jMLJf^49K&|0$doDuxi{-HQZ?1TvaKd1h)xm{bg#ANAd6w`{C+zij1B`!lP5G!Tvy#lU#GMZAQG zI0YiA^uxa7=?V6k4dJgW^DtiYQKKmqgTGUW?OJ-A!lD~N>$=y2XX5thL`6aXU>@_p zNO1Q+SjjdQ#E<%DmNKfccpG7i(p9`MarUDWpB-tfgGQsF&r6`$N=Q4*{S$?EcY6Y! z>OgT3w|H9MU9)j>U#7-kxpKNnOE%-tNYZc@DL?wWYn5{kCt5@ovv-On(LoiXXEJ1* z=e!jk$j$Cf+YwXHb0$jgG49&Y7==<*qu+{}>Ynw^^-`;6w-C<`*4o$Lt=Q2#h8Qp; zrB8bV?HP@v0mfh?c!hl76)-R%wil$+U@x~NI+PzzR)C(iiD`_*o6@XXzBe?Nm>@(KsVFse&N3ZOJ*QK73g7B5u5y!=vR zvPMX3;~qc7fod;2h5WA?Z`JNpO2SpiWTvbG!*G8WtdR;pQWsB)N5A!AP5bSRHglYU zFk=6YIwUocB4q|`^`bYma_vvV>9WihQ!lZ^NI?D_H=iMkF)2=fu5_3pw&HDUDd0=x zH3)w8$Xv=Wl7nR`L|>?aaj~l9VWAexqfJDnZsW>Ndw(SXo|AzZ6P2pqc{vXes<#A47Z*MK`O%oZgRO2I@hn@Y9cJqJ?!$Ns6@9jGS(3&ytX-I zBv3AU9Uss>$l)2<;kOfRo*{f26EhKsi279P$lLI?JbxH+!Cb-t-o$2i zM~;IHND3%Xz@~;769iTcwzQe4M<#*{Gtq`@C=h={kGihY{DMVeuW$WLYFP<)9Wwf0 z=#rxD0D*ZpCEdwe9=fV9->y_*Yd#d}9r2!-&#*dHrIC@9mH?UVciG_` zrWdPy0e&+iUcPGFD&PPOm*fjL7qx2f82M(BKk)sZl~m_dVQo9`~DZBZqQ)5`zIyEhswr$XMo@_ZdpiPFb%g&A|>%*N6@EVxqx zla>egakAcf>3g;)@y0GsY+_M>9U;T`CQ;CrY~mrj<-D1rq|b|*_!><;M=4dc{;Iqz z|39%nol#Z88xS-d+XC=+oZo#!E@|42mI(b^Z`y7VC{kU!g^Cb5xtPI7PEI4Yd;9EA z8PY>SL9sos7UZ>Iich_Z1(-_PBT*5p%-_peP9I~`16R^>4g;Uu!IH1K*@Wv?%m`20r+(65*uJl<&qKw6adcRh+^)> zji%LE+IJ)cs&&Fid$;pWL_W7?g9rfCFFgL)?8c&q?Ilv*o$5^B9-f$}U}!wL5#l7+ zMhDcR7s-@JZpcwiJ0jU%ixZ#ct~pJ9Khu45L`Zx!;wU@-YSSxppY8b|^3s#x@wYhj zn`_avU?oSbrTWbwCf^%hS-qC~hmRZ_A@GxQZKAY}+MHo^ z-W%~jB-sKHZEFgWoqx}$_ngHNkz`HP($!0PoIh9a4lyptcTGyl0zS*F6~{3OQWe}7 zfswCsXh3^94OX2OvP@4{VM^Jz#sI4ZRg!t*eKUZ?(l_)6!=f-ouE?to$)v;>_+jN- zKApeiMpYzTI)hzJb9jMSYr^tLBdWSlxFca`oU;g1>wpkrP;;&QRNyBJ6-yI8lqEyg zO3~mRd4a!b4WsX$9f zi9==Df4T|fROs)k-CLrUp2RA8qu2K-0=evOz9y(96TK!If=bx^8?nf)`ndoSmCH8X z5>~rot#3x|nv%T->Nk>DWQxDCK778X51i#|cq-EQO3)OUZ=_H=-ILp0i~azGWh2u- ze9`{_7oXS;ANubs64x~1O{mbpQU1T^^ZCkL4ulBu?AOl|uR{MxnN$-V&=D{yOAd{W zJfQV=j(?ZS+;LCyXZO{MVk>RG6-Uc-&T7hjdFR}bjog&2178Z!3b$(x(rL|OumXNm8Ul5({eTmWq**NaO&sQ_7+$&YdTc|xGCl-Ri?fhjY z&1HY)CVdVO=}o3zYrmYO+YI>QD(t21Pi;L#1(*@%*3_+>8Gq^pH{jx1U?y}|{&E}j zS#%e%2Uww9g6DjMhL_D+lLgQ$;wsr7*Z=PEG}1Re4I}jY65;Mc>ZuGJrDfz)=p5=PoHP| z{axdoz5L2xotuRTc(UC3Caz|}aOBCx8IV(g0;gFHlBa$W_Z_3ndLGzR=}x@!^1XOx zDsYxt${pPZeK%6J-@$x9KFVn6`GW(cGR)9(*AV%h;Vg(a$QwTQ*i#edeH|_&u!peY z!SVkF+ojUic~9TXh3bR*W-gfphLI&c=&{s2L)TB%(sx#17A?YO*vt*o1~|p8GN?&1 zWB$VNZ+IlLNf{E6xnU0WYTjpL?=XuVW6)f{^cULHAxrH`1wh>qNoWGh@$cj=`LJg3 zJ#gbOuiiU~C5!1o(*Rl?K~RcA&RxJDGq{Q11;PYzdSQ#WY_$M*618NIBp%@}z$9`2 z+YzoMc0pcIr6jy>*HUuaes!n|wZ&;dA$|HZE&Ndmrys{W!5x-#cY7tKmtsMOPZPJ6_aEko*)| zg`euN_lv~l*-YuQg7cVH5dqt;630ep--rZcyl=w*I(@fbkjm9{pta!5wL*#VPtVst zk>#ZIKMoB9@I|^38qli|x5Vjuu&X;zAJSWOuP^o71V>gB ziVBPIc*S&!dR6RTF}wOoV6cMH9H%2hc?;6D-pLxp`jyz~%C|?mXip+Rf4Q`r8Lggf zD&Cvu^v22@@~iUvncBIEx*tIekDe}t;uxf<(z;eF1Oh+v2?l9To3~;<%`Qej5J3eK zDa69i4ue;<<(VyNE0pXJjz?$^291JeYy)t;m3 zM>2R*9^P0yi}1^wqkn7b#{8dN3gApNgrQ zfQ>x8J*s|UY>iT@lhm!pmx*in^a@Pa`{_IQ#O=X1dKLdia{ezGV&QEwDqUVk{`(sW4`f{4XWl${G13xm9vd*Vm=I^E95eISHqGsuA}^IhcmD+gEjn}i z2rd_NOep((*;dilPD;+Q-R-E$ThNfo5G^>B!QV7g0H_rHs;)@ibvJsy-$OfR*>Y_e zF-XKglPw7stN+NHM$?VWROqm1=5P_?1<8jcRZ^SEGhR^NKg62IeUjr=!}62OMpdJG zR$!1L(s9~(wVxICT4%w%8v1M)cV_!HPN_OBhcvVo zKA1#!5O|&XollUe0mYClXE$#>L!GH~6jcM4v4}#H1p{z$rh$i5tcJ|x_?g`a%j)>_ zG=#hly}e^*6u||z{F+w{LG({Mqo44P6flyQ&beGP+?s&RJ2tO@80R}COF1m{N4>kb zbUg>c&W&9vc!p+M*7P{H*67%DXIsnTHQS_xrfA|+tae=VP^U^8nP>9p3TsD#C ze(pE@o>Pk=Q|hYFgR6=ey`S0UCJy)<_V-+6DJKS~1ar>2$L&^Hb!E6_^SZ3%8dd9& zsMo7=ac1Mvifb^-6`cs6FsY$823$@x|HmH%!gcf(OvQQ*!I;e+ZV zSkLX)_`uj|2CGeT(_mmn0s_Ixphz)maaaiUJXM@mcxM>=ofq(=XM?rK#~x^_(!r?~ z9dL)_8V69NEZhw5W=eewL%qzOWQ~@=qm;-*X$c)xjoWERG)fAA584=bct&RatlUl_ zFmGbVGaDQTu3Nf&4*&5pR49CJBwkT5Euy@&y{LE6#p{klz$orW6wi{Ic;}lo%szMy zw!!L~EU@x(H(zQ)FlEFi20vxs5zkSHgh$~rRSLdv@h48dB636R_V93_?w84!#t}(Y3F*}3#0xwNCMH24m%sFPYK8B1ItxYlR8NbBhEv&xm@gPdPkn}b~i3&XMn8N8FVos(FJyUBM zlVDm$b_J#+!E}lG#;!dyjWpL2_jI&Z$Ql`W3`#whTL?(w>(Uk_9_i5dvU4W98}af7 zrX|kw&d`^uN6?hAK@J+V4@R*PTaJd{zPOVHaZmT1sDgy#H$4Jd9@RdW6!6 zbeHM%5!u=TP8e6LI<1Izu}wV-#{#58l(jT%v7)cj_Abz`e-BylE|aptCQ^;nI-+%(I`8zJ_A z6%5EP9v;Nz_3H5oyMu@_u%7ksOlwP*b;j!I=MgU!Cd38!8On3^!5GZ0w`gYZ{(?H2 zZRZqpP}f;2Ws~~?_9u}rcxA4T7OkN|Ei=dS=M|U+VzTGnjWB(SQfFwrU(o}NK8f1v zaE%8S-)1}{(W$e4cVND$mXWC-aJh=>tmK~n>Dg}LOC>O)P640?Qw>nj74!_F$qg~ZV4y*4ZBmb&`z1BCNUEDo<)P?(s9yljUp8>Tz zh&l~?3N{1mGz|i?R?&d&sv1fNt>s@MP{Vm2DrW|+yJuJ%e@Vb!Q*y4ki)^XGFShA~ zF#uhB>gClSUg7{RyhdGhjIyPhgWF;uvedGqyW8Id*$DLE^^Q9bQ$eyZ_<*4SxkYed zmL1v32Nuk$lElwUo#VNqb81xiKqQ=|+ z^pq*Wkirq61-UCH7Iz76q3|R3a=U87*31RZ;C!wH+~dM;VC7CSXQMl@(mtgWG6m*7 zs8RzeDEWG+D{FfzJHIwELhCj?uy8VVu~B9{g9@pome@DT{GjO5XSA_it9NPQNFTyo zVo6X94k%tX?Cd{+iVkEewT&NojR3tJlH+!*O!mh+b68cQZ!HRWE1EsCj2U!FYmQZR ze|`Y)W{=_yq3gU?fr><<`;?^ceXRmF>Bkz_eCAYGLd{bgen(JMrDqi*i`fXh8Q+9G z)`4~8R72xzYOd~Uvx=hR21cEzbAE;Jjz1|mmiN`#qeiWon5^j4P zrVO{)voBe(Khi$;BE%sY3er$TGxr5`NU5uep`O+;{{}y)GkbH(PKL2Ie|`*4RsTM@ zH#>2f@UP5z4`M|BLRdNFy=J%!Dn>a|UO#E{ao`fH%uq*VA!bfz6PF6RWIHo18}bs8 zgDcgBEV1B)CyGhxghia!dYPvSu4&gK)h3rrT({2js*z0H5N6F(bGBOEQ7Al?Iq^}D zSlObr*)j*N0;ma3d)T4q8ilM*WcAr`$-rL+y|AzPLtIeZpG3Cq_ic8HTY*nY1`JGL zw*p#v;DcXV(QJ_FXBa24)Q~tM&46C-U-RwWdGx$*jD^sT4mYdH?QE1#ceOv($jJ2U z))yffG@H6PSIPWE9HfcQ>h{F1P)LuJ{E{3JmlC?3Gt;gNf#hEZFK&{2M zMGG62P-^#K?W!r-m~i!B90BG`exLiT4qa%}z_|JK>+^}}4!{08`s3m}qg>0r%F)`B z+`(9n>M}px7VP~bh_M5}SL9<8Uu=rYHY`V2dt0QwBOc})ImI$H?5+#uu=L_@y|c>+ zo+T)vnZjo;_DQ)W*xMk5#P!wrQCju61Vm5l-58{I?e3yh98vi&<)UKi2KAwXS|Wyx zNj!wMfO!KymLS~t93i0Q#u5u|%0OJEZbhm-Qe?d% zU9fuC1Z~~#DJ2*y%{Ag z=-J25M}1G>^UElY*7H@P%%C|RkECh7-!a#+8js8PqDp4k-w_=@Xw*%cc4fdu8CIuk zO6*VtlvH?=2juLwl*4TC7h2~}D-%CGIL+;L!0h^FL5)C!&b8j!shVL`Uu zt(jFN7zB>$JDQqQvqJcXmkO|k#!FW{189lPGInPWHlf87>*;DU!p!x2Tn1-P{7%{= ziWz4^+Y1G}c~!AHz%{5WLVD={=#r6CxMLmYgZk@K8Hc8n{E$hQN8nkc_Ra*MKK=v+ zTp%7AFs-scnRhb5B`;dFAWA-_;hl8^zl5B7N>pYxH;Uw7rKlW@ny%azP~rmIsw#%~ z9iKrI48TM1PpPvDD$4uqMoebCu({_7Okd;6SZ9ZCcnG$KG)-3tt4D=VZ#pZ|Z7D@@ z^rGk%(mzrS$nTz-Has6zIbwTn7hp=_toACX=M@|m#4Z`~D3~vQ7$pGnUHMp3Cr#)J z^)(SHGm#xc-KQ`3+#3)zjZ{vp_n+t(8N&RW&1$YH*JlbT>)Z3}qmqCr@tNmadXztI zo8h*SCv1`}WH#p7A2un|8v%QEGp^y0Jh#`W?+fgrN4Ke}(kT&H-;~_1en!!lSH4y0 z{}ERsP`1$(?+)({qoX%}NP@N{%|N6^NVr?0LFrcIgXz*rJFqA(%2xkg3xIUGD*Y}Rnn#MQuF|g?$3x;Hw@UDGXx%b?0NwAh z^S$?h<$;{HWcW1ok(*wwOI0RdfRjYT+4=h=uc+!+rip?N_Odg&l4u`?QqTctgQjAE z4}jT5dVvGI#~h}v@uAy2K=e{IwqESB zoDHjv9ubP;mf7CXhvh@Cmaib>U_~y2!e8OJ4J>grh1|chxk{7d5~g!5Cg;J{bpVDv z2<&L1FRJ;mElI|=TI|tj0|-+Ej0#J|ZGTmMKmzXZ32GQl41SZ^jcWsaf7>vOvdjJ- z{;IvG;;)7vzVJdijKmJ|b^W4iz9EckEY?B>`}xapFd zNpV0Y6wpK4TGh;|>;~x7+}x+lAsH)o!on&FQJ{yO$%23$y>#RZN!Ik3PDMfabn-=2 zO0?u6Yx&%(*Dfa) z@)G^G^bi(QfP#;$)9XzOW+9;qHc&o^+DSSZr7+~V;O zf%nqiZE6AaBLBnhsP{9_fRfEoqWMaQAEjAz?({SG&LYQdxl>0wmz4wxb?ZC~_4Lk# zZNQz3)6ub~d%Ek!_1VYj%4TQ>`(^1N)zkV^^+ALil@Xovnc;N%R1xxwd+9~+CMS{x z;#VjoMIxS@W{X?KICNV8r@I3{^7z<*t)NWM(20 zG*xfR)&W`*%97{RO$J8u?J=;l9F%DPbk#9d;(76Q+&l=B&&um$&v)jEJJ&}$n*w@0fjt>+U1nh-S}bgOAHqq1~MKZF0q@fc^Zv@3_DR|KZE=e4g!rfDJC)4=c*U zhnoXEr0xKJ0#gXXO5pQY<3q@C`w-WcqVGgaGI$i9O#7!xTM2mDhIEnH$o4s9KPE;o zM0)W37qBb95ic;vaY7qGjsIZZc`d@%lm%H#)CcY_=TH@f^U z)R&jS3VnPGF)#Nu@_v;ZCz9C5&%ml9yisq7^^)D@QMon^nIiu4bc}avaj2pP%gik; zACGYOt|Awk7sXE?99eTrn(f-q1-Qy$s4)OEZ9*$~s-EC3dnEz3uXf0gwZG@%Sj6Oi z{X-ad8*1iS>xSC)_aMA)B-^^V9K7OB*a9{*_#`9db>$1>gN=aa+M{B01R`JAJS z7oO!ovTNA3UR>di#EX|#z%3ZpWsPO?Jvx)JQ3ln|_W@KKVQ*2dcoo!p`%-zlWk|*7 zHFS}exc^9A@yEet54Fjm;Tl4z+BTs;0&A3C8=$$xyL~mJdH@eB$-n)58W>ugGXoS^ zT=z`SMw%bG2y1DN&I-}UKt_}Ig0deX`%ro%_igkv#ckOC9XDm3Ox(6D;9YP{I{S zX?0OhA=7q<+9iWU43jGXE48(a=cXN}WH#{y!pB#kfNgqsc-ww9;@z=wc@FSZz|182lY8M^JHDqt zqCpt;Z5*3SeiL#6{sF-!K1CB~r{^@Jk(wv&*{j>(Gcbyny@8AwCR0&6r&3#VeAiB! zF`-M#T1px_mSQFUz8ph@FzyeTxWo?=BMgvKIK`Xs)S>U^8LXWYuosqR(C`Eq^G@!+ zm_^3@S{rWZkxbMmbPdmGLDF{{@D~KSdoq?SNjsaJ#%8D)!#*ww-|@3c z!Q%kPl%a3d7XC9-O$^9zzyD=&zEtMg6wHU3A=Pt_I&MX`tSq765MWf=5qp|Feb%_m zEi3*|x#!edQcd2XK_yWBnpdh1Uwv<_-@jl57!$pjoxk~k`_OwjcO&|CsJbANF+a#S z>5=XURrhP(p%Q+k)?e~+6BsbLrgu$-17`oCPkI6LVzyppy()i3yueE46}1zeW?P_^ z%I{Z`B|XDcGh^=ZF5Yu|6sCBZjJQ}@U=t(jx=|X8DtwSJgk<#EFkDO}*3+hw?k!M< z+IET?DtaF!&q=F$4v??CcrlCQH{9@1VHk^l37?_WbK6gTF_w8-2+`$!z5ReTY=;^A zyR6(mq5>XVihZ(H7kBCNMjWw?R;iEYp$TeM+D$yh;H;lv8E+*S>nl3zILu-wW%uyX z-2_F^iLXj@Dsl#H76QdH)AJMZd&*jlrhIYETiIBcyRBc`BecL7EG7@i&uwYD3~wfnQ!Fpg=CpS zZE~;rLcDxN$%pdp;TeF>8_Z>eN|EUOzh%cF?#8?_6S`+xr`EE;bOA|)W5-tOIP%LXgvNK_57m?-#W;?ibv`3*cd~)pRh?h|gLGTO-zX%uwVS7JCw%f9ajN##fQXNx&YQwzr&RC)*yH;zXl=4E{DkywU z=*3KIap1qjPois-VtSABrfRl`B#LX7l3eP?k`}ccNmudRLKJY{k+MAHH=#N2SNC|f z2r3gxs`@(z9-W;PgnWB7Nis z5BUE&FQxW6MywKPpW1EN?#37=f9XDfq$YtOcKQKV-GEeib}j|7c+-tPe&rY7tS1GD z{Y;r9j`K^P$Ow+*IPsE!4Z9KE+p=29@YyE3n&)a2&VDc+sJ`z$iEEuzEZ7Tc0r>)v zXR#_#rii)gF8Rc}at~*5#Gi{W3Q;lu#LK1+!Pv%{R7yAOUtCOT@^$1hx*8oqFEent z*=&YD!rV$vD?Q$VdpNV>@|V8hi|J-8(MOfcyDW6 z<+c)llTNt+MusM)wL(RWWoRXSJSj1D-?Q~>zel&3`Zq0aM}gluGymUkLf|Y zBrb(8O7B9rM0GZrJ-Ni(nJzS3Rof0qV3$6b1}iVl$6rDlqWQh~Q3$+Cj>B!4mLwx{ zR-OtE7s25UFsN>>Xo}^!2X-i(`y5W?;_zcC-~ci}&A+ycrxHO#>kp~GLY$e=7OANF zQCw(3o&xmW)ZQc0ZZ?vUF}4yMNv(b%5HVY!cC9~B=kSUa(g|El(b4wxirk2(bXmXv z{Ut$^j(^Q$Zss?f*kVayNh|_n6&B9nV3+@>V|sVCh0}&`;0=#aBry{6CYlPIV{i>4 zF6E_sMWl>@Ny^{)p&oipwvsDv80%ee*(e0D7Ch3k8Tomw)zMJoJY}>l>E9qgly$0J zj6uiY8&WeS=kL$6fvwcu2ipy9ESydj?%QYt=%t@0eJwP798D$gJs5x^ON1#?_cTeG zUF7W+ib#5!%bAUAMnXHG$A5flmt%E4a^g%Tz&YmJ9 zueuY669jINy9zkwoL_rmcl*)=&Z<9`bztQsNDTO&(kM7B%PdM0i|u^UeoX2VO=v>0kCOhu?%RUHQzYJkoxxzw4d6_Vw>Qh@&W>TGFk zpAGm6w=4>^bzg!kx~jsWMD{xHMDgN09MTJ{9BhdH63gXG*?XDtxcC{+c*{0LmL?Ad zuP3SW1VM}!uv!-YhkOk6k(vnU=lDGgl7~Kmh2aM3inSa+8pSbOn!hnlizVT|jxTD~ zruBHr+-E7@FXmjpXwwUv2S8Z;J+yJ_uOIP+r3w1olttyd6?sk(4G0i_YU-N(cI?`_j+nfuOz57^@_*SR|X zoW^O$)P}{51pmn;MDM!Nup@Owt31h%&gD4b&HUUe1JG@RXhSsXts84sNO?29xSyo2FXQ=AL0lVs9z@1*NBEN?z z=M4O7o(BKr1}ORgz6{t(q(3szWG$Ui4eI+1Q%}=x$#!7=6SeJ|QD`4tt<$#8X84O0 z6eV_-vEu93YyLCg=^!Hr({LYy?JinhPZrsZdW%@=R$BQ^s7mzC441{PQMx9c9g}Uk zwNBT|sXy15?zY!@wgaEJdJp_e^uk~8@IqMqrZrL7);<3#pSu%2^}I_0+6Qa^6d>N| zzaNW>sHj}H*r&D$k1$ip3Nz@c4PffB`KKSuNb}_TT>CibTXXz;p!-UW^{kbTfWpon zDKwS#z(v?3=u>|i`5UZt2z5wQM9jsrppE#p?&ceCvRGUzk#uhag@pWnMZ!KJ-fj2B ztS%#SP#ax76`w#pQP*J*uLW_tWgKME2{N|(P*D3zCS~mn;ToXiivCEM^IqqVBztD(uf6k^gF-dXfK6gEGqL5DadY^ygqpj%iJ=q#-t^O$-upW4)nOfz1xgnkYt_9%54w z4qdKlh!+Y-($6Bt_;Y<>MeymO)MEg%LWG6EH@An5m1N7t9gBqJrg^S|NX~Ux-)u@Q4Vk; z#_l$JyY&ZYLdQR4*m6jjf4Jb9P>VgB-HB7R;(zl07gYpue=PqLwo3_M=@?d~?tUFMFhr)i->^%r{Y zkCW5cD!CV)=?caz9c2_ngX)SDv3SlM(MI6sbDeAKjb$6b7xOg9rgp7htAR*LHmEdd$r+z9d#6BQ+YnUi zI*V=R`PUV#>7f;=iQNF*{{+o&b17Fn;$JRqyG5*LRPsBil#KcJUHV0i!dIw7-(y;aHZL2g2_h{~>EM}Uyw*&Y{YPy# zP%vZE_4E9>+z-~s*f|nk(jMleS+5?fEoX-Cv=w8?Z>er~i;)yTp4FetXi;**b6t<2 zHi$0@dv4~XSR?uc8PeZ4%PQwxbEbr;18Wo(DyI&|oLm27cefzaNR4nu zDDyCF56PVoni8fk2y~=44Ukj%(|CbGQ^Fs0zjj>h-x;Q-+9gAj{;nXh9+d6YE`ny# zO->F+@YJ~B{QOy0nHs*|YM<5|g?X1Vjr*fANg&XVF|H5Q@T>31^^r0gIO(3?f^R74 zie;QSX8gPV810Say&Ccq`WD%djGz>ACi_8VS723bvAC2W<}@u8&e%R+W}!>*$Dsuj z^aUjh1~3BmeYGcWW0^P(#%Y)14@pSvD$Di9XDjXe1RXVSED~>?=ghb;Jn!x0EMA)w zcGb6`?U}K)z-KDq=1@vea4)?IZ?Ig#H(u0TvO>Ma!H;}g)4)?GAHne8Hn2tIK&$DM zr+mO7r(T`yzwpRx;E5!?NNnetS>g2=D*!i<-;O)zT<}``@i&)vV0Iu}U-sWA3iDOX znNChUNj-=I7@W7yt-Yg(W?n|b7no4xKp~rmW*AVAwt}_2wh8VAU=a5cC@rFC$mn9m zt6y*dMK^{%i}=!MyT;-=o)_JwU|@HWFEq0|=E)H-e8biE|JF#VK{I__Q5SkU9nxjl z6wZzR<7x-oH*Hhw+P1AeHG>Czo}}h`Xb4CB@-W6(ROXCLB(y?P;#Htk6P30XYScB? zHOIN@=ulZYCBZ-gisr7C$G|^# z1iD@duwHe1>h6=70-g0hYi&=vcuU*u*- zq0xuKycN`tAy!}-Axjod>7w-cb1pK06eggSJQ|Dz(tBhXZ3j;1!o&cD-UqYTvIgav z1ZDCHR5eH|1C6%kbA(_a@L~(gWq+>q_V-!<4uZAQG)aK`0Q2}FR!(`lxq6U@HYWwt z(}`cY$CCdVr!M*Lp+9y#GM@>(%yzu8B7T*mojm2LuMa{TEiOB-V{RD^(|EOP89AOi ze2Zv2V#^&qif8H_`Q51C4r58%{44yv6PCkP4!D(H+X$)zl;z@f7uXSXR5#Icpc+gw zTFKS(#^e0+vT2~-__AueT!MwH%wp$+$oldztsc};2Gq9rVs4v2$NEr~Z-<6}arvyv zkaK6HuAAW_K3?%@DDZEFrJIJZT+2vyC!gOPp{I3))*5)w2f8O+>0(|2g9znO?Hmj9 z*II8%gvbWb;va|+125?^^&c92aghSmJGCb{Vuk%`MP6gsmeW=}&XPOMB@l|t0c{^w zPu<&d1J}6NMth$N-bAXJKmXpjFJHk+)2n#b&1-?()hW53q4)oK%32!Yz{|pK+Kf!0 zXuG;#N~Z}o5Q!R|G^k?>$37I_H^JiXRk;)Jn+}aFS$RUr1g|D#0=sz1B(wW|5@lxY? zg!0oJ;5!*3R0nNIg~o31ojW%@U0i>Ym#4Pu89S@W-TwSd@^3A+kF-A)QlUH(gC1kX~L5TZJ- zg;~^6Ty}F~uqFKxOB(m^Nij&GCf)l$dEIGrB_(JaRgZt6C&FI|x!~k~8#Tf$_MuCV zZ@|kp4m(6~Dni!lpBwiCh7dQ|ReMBmffLuj1FrEHC2Ry(rn9**?dh=-*M;(6gm0rpl2S&zm*P>`3hNUxM~uFlxV!Be2v=|ozLWqRQ&zNQ;k{!= zsVfe9bBu1+l>iM)4}N{CboiUt9KuqwcAzXYt6{$AudwrPAU?0~Vuucr3M1zn zXpTJW=4k%>Al$J_M}xWeNPsJyek|%G%>WX!rl6Ddhzzd=J!tsRgz}$CdXdYfv(j*1 zL>bu?;Y(*8dldMo+Ty!7UFCzf3i(?GN;S5qZ$HW1z@MLdzDxr|q7jSb-n`rP$JUb2 zT654;H8YDaa5OOI6yawkU$tu>ft?QZ9S-fvx}5x;>s`k@y*ZlfnZ7J?sjaI@BjV2O3df$2>s;xm6g6(HK z$tii1D(rBJq1va&l9P#hH&3WlxUNwQsuq_I^hzwnbeP##P1`T98@X=9`C;pi=Ba(7 z9%Jd#xS`UgAg_s|J*oOljI_P%a)K4`n8i7+|6dyFrqxjv(Y*#f7j@w4fxY7Y9X^%> zpR0qOb8xHOn`0FX_mb#KYXIC5zId@SJoNR`j`LL`*kH2pHTGy#jJ7bS&v-8HjaiAA z7Vz1PJnO2yr`gQLcn3k(^fM&_{nY5;@;+~d8%P6ATUISShrfusfxiCa_()0ZN11x^ z_;|uFfjGo2LEaUEW3w44>8Ndzu}wX0cYfLq4`eqIez1gO%_Pr%$|p6+YCnGuLvN#2 z^;2#5ZPR3OO!G->#FnRT%~PXEH`D&pfB>e)&W+8%;p$G4zQT)BV~tYQ7u7c9m@W#I zvcE@3kj$slth}5zkDhJBjx)QM-aTV`=5F@LsVPTJKsD0E!i)H|B9Z@KGKvPj~zVjhb`-@Rz!_ z5K-6EIdB^eoS148h{q|o6CE0-HXAX2A7(mK(e_n@4O*6)-9Im8rR==f;M`G754Z*u z97Hc{UphcPvAr@f!MQFS4ieEIjky2iQs|o$Vh5%BAVe}-mX-vnUah?%A$#G$v_Fve zJqNapGyMS_0l^*A^>_o+LgDRhBrhfk>mWhJ6v*n4$~Bq4a@(K+!Ie;tne=?KAB^eh z{vGCsNCsy$-9U8rmf(As28aBHl-t%5+van6k69zWYwc(hzR!{13u%4Y6bIu^=f(IN zBmvdmCjQpvFLlL@#j&6ExqAKZpwRw8Cm+y51e_zc+5TV$Nh}a=obU=lQl8pQ=~1r3 z^k4}N<9|&3D#OVjfU9PXn~by=(Mu zR0ku9(}_&wvpAe0CH$$rZvg`G1{JYce)*H(#PbZgi6yR2O~ofTKH{i8FJK&HCMAi& z3;F_3OgQT?S{u_Jc-`6}2(=<~i>m*`Y2U9(T-KGy{R}nxf7&$YXGN%nm!o+1_ppe@ zG47v~UgX(`V=5_1uXx7g*&Ww}bcq~CtD{KvB@HSZ;}#+5REROcV%TyYOf548yP~>6 z6+bu_)_Tek7?1GN&Q@Xu?QF&#zA|SR&)C0J3sb(zz_t=%sz;O3QT@`{yWpB>);6I@ zGW#r4R!o*Rj9Ziah38V|unNt7^x>ss^Bl_aXFDvRr}w%3g9XxVH~K|l!<2KOC)+TU z2Q@EsEkPFmL}?yf4cp&;vzbuAeO$|-oD$FPO~(f;HRUKvN&p!kP&43DS+6OypE{q5K$zof#*8=>^6j zogVfEPvuV9+9?Yc>h`@f3;0gFa zbbD(o7r~!YzMYC?j!%@*uv%AP$alcp-u{q!Syh2CD_X!ZhC~3!NU&fCm8Kj+cjTVj*;ecN?FMn-U+% zcHlzTQsGA|F&j^0`x-LOY;p0PMR4tK>d z{8T4uEL`+YKUtgPwytvSr+Bg1B#jcGbs&+_|2F4T&X9o^><8`*Zo1vXXol>x^%zNf zR;4e83T4UW>|@NdZ$$GNM5R$mrDxH(bykzo$~ma=*M6yS6$&WnM!af6Nv*BBhA~0j z>fWzSnfs2$l)YW^RTA~&v(v9%{WRJetD@-|KJKj~KByjL_)iO?--<$IffP)M#oU6s zo}=wD*FTrb@G$eWeaR>8Vmd)`7T^|^R{sO%e?!B`Iu+0qLI~>wWt6Dh5#zG4)CA>f zQ_i#xFcaCR^442h)YUAJinO)r^ES_aH}*W2Z4O zA(C0CB!r{`FQ3F)%|sJiDoWRor4n{v>ZV%-elEpIEG-`t&iiU%OOB-sZ|k9=c>5`O z`9+r~O-(JnlNGzl3gOJrX$_GPS}~;%)B8lrKxM*$uHVH*L`;DMs|YTsM22yFa`Ry} zxZ1kHcn71Ohc>LyWkdc0!u=6DR#c(g+HUUSWo8A@^AM<>6Ra8?r5>zvcmKGz-G+|Z z9dwcBXa?ZkVkuZ`F9LCA9BX=5yr*>u=Q6dWplE!+4C(P^O#lwEQ`2iUwsFK3F#H7| zEw(5n5?SJ+bR$Y?PB5w79|!jNCPZAJU^R2ur{H(@wOfx~Byq*(2F4I7p8s46+s*uO zjBfw)YQOKGn1~KvIdE_vOW>*fx1Dh_Ov1wfAGF3lV*>7&NAXB#reaO(W;*w#`|Rrj zPmXGqrbr!SG|Phwu-fbvxS#$G4#@(aPdP5|3cJa#;3v0>2gze)q`T#SYqR>G&&xh~ zt9_1Qm!tkK7Z4xhTf)Z~MYsx}omusNIu~_%!%PpU2XQulS!VT;AFZ^f)5b^@B8XpC zS^;9BiHZhq#9P2w#R#!ua0Xk^b4STBcRtlNL^a6jeK~o0d+I~7a*lDQ@~DcNyW9%rJl;p9=eC#i8!vujP!cD9!-?e-fM@b$}kG z0-g>$k?!k9Oh7=O(T4CLgJLum5oCJ!B3*#DOh+XNmIix#lAD>NxbTMn9{5k)a%v4> ze05=Rmd=G-tU4=+W;^q5MNIy1?2q@g6|ca3IfI7a3dpI26#NkHQE+cbxTp3QLH>V} z89BJeTBs^L#x}#maKqVik$S7nhEQTrN#9W94_m111AG}|Mq{hAbc|Jy9v^VvomVen z1akCL+kZ#&IbgvX=w;cqhf${dxDHAcwyX#1^D2 zhnQZsH_R(Wpu?|iE1FR|g;6oek%AbQ+dd_Rv z5Uu0xo(Z7^NR^Y=*@wR@z>1bm8kBvC-*bT#I$c>L;@=hsO1AXwC_pSC>V&Kz6fOQG-^KoNXn0#h%ULLpk8`kF|$IxvV zbLh$1FRx`;76(E%8++=Z8E%UF`pR53CY+B1duI5TEDr9H*)mDGYsXSBdoT0DBm=z2+h#QYlxRgZ0Sg*huFx5Nyc2 zeT5!XawQnwqegt;)L3fJ&Z3@M)wXNk@Z{w|k>l0{mSFHqH$~8kn1!HaE=OfqxdY3j zpJ?Q)Q&s8aZGsRBOx5NDG7_=i^S&^(IP!IC)%tPsM}#7Y4D$*H2%CYKV&;bb=&>11 zzHK?RRiy)IAbNWA-uMXeyl2Bsf0?lrS7Y9vez>T!ivm@opu%v9QPcXr?}QSHGWqp1 zxhwZT+z@vHj-saY==pYHkqKTX()M`4611t&*!+LP9@%|4-Rsg{lZ`Yq%p~g=^Y`BY zXEBZPqBnewE>ZoOeqbeld^bI0Cd(Or@K!3zC2W>8SJiA2BDPyL+Zo;wI#B3Z+0r1E zriAinjhwufpYkd2ZGC&$S!Oe-4jKDC00hv`N-BZplpj??2nyE97EV~-MeSfo2R+|R zsZa12UD>iEpaWyA9kv_oBStAr(3|aNu?}qCts6n&A%uup#SNUXfXh+!Sw+Lk`kF^{ zJY$oR2+1D-RcIz_yk=xu+6DP*bx+Za{5-S@?rX#?Im@FxPh~b-)Qy>^5r+`o39o{3 z{(6HIF5GIL|0?_EKNIXz66%NQ&wh?+4=e|@qA*-guCR!w%=6#PeuDl430cj(A0q&1 zW(Gcs3O21cq&-Hse3q+3lnv5 zPFAI=el@)?lhIrM_-|Lr`}F&(DA-VUVGCL&L>pSTG^3p;k&QLKMLL2ea*Z~4#H=iw zLMY`!*XZ`@$wQjlp3rE@L=;@J;ACkk_B!?iPnOO_;QE6!LmM@U!3zQw#_it`1tN2I zpQNHybeM-u+rNXviZFXZ^l|l#C=D%1YN?rfnmV!Rpw$BCmgHT{!wtYjI0PPouv54oD4fVMB$IJn7Rm7m#nfw=N$5-Ks(U|9_&WmZ8^k|)_}0l zI)-{pbF2*y_)Sw-t6{S{3HK@zRT}8{NljT%k3Kcy`l<=eS>lks`kVwDPlfpf47?9i z>NET9$-b83XBXlc(8P%-rRo)1n0dX-!z~%eP|y7M9Z|PRtq(mOM4Ywf1Oc@tE2Y#B zEK<$sLdUL`3D4bE+c(M7>P>KZu4%3y%vwQPp96r@wTK>=je!dP+Xh4;@g-L0&&u4f zZz-rW8w(E2A|Z0!*v{!p2@Q63$z@VK_t~zBEPlKW8RopI{%>!kZlC8K|1#dC@VqB! zL#5o7mbd{}vuTq(dAbnu+Go3K1Stuptjw+7wYeNyKFm_b@V!zEb3I4B7D3^a`}n9~ zpSb5qu`PU&gsPhj9Bp}RQSwe{39@>qGd${HT#TZiR8E6+nh4Wbkw$rWwsSi>Nk*kyG zX(|G_X=R#QtBVi2ObjF{eVZWjSSUL{$JFH=W(IbNqbS=N?+3zM z3%f@ai=-TV!*d<-n4q2E!}(oL`o4KF&x3gXLG?uBEDjas)Y^1v&cq6P{OwEF`j@N5 z65w}rU^PJ9n`@zyMfl*n_$k|jNbC-TkII;^=@YN<{yS3 zf1H$3@=FMDh`E72YczSDa3t0$UB>g!4G3rH5p@VpbT1TPG^7|(>L>yVT5mX?4|I$M z&G&g(PWy(2(YvK4E9oNe8(1fU5L=;9Kpn2gy+Nix;%a0wQJ$EouUF>qw9Q~&>y;-K zbduk7i$oV0OIopTGsoRTQ^dkhYx0tHgcK}d{@EVScAP@{iD4odbD!Xg;N9XpT6@Om zsfJQgR-xBmSY)dE+pvkr+q))^U8Y1UwGuyK2gxr`neVfSLj0xe!2}4UGHdLQ7Q=YO@eQR z$?cc+Y!=AY^pGQ>bgKJoPU1g)jKnK6tevazez`i5z!-r?PJo66|NE)~X=2UomO*+Q z*AIW$Mgf;K^$nl0+}xCEso(?7sA6Dny7%fZvWHx#2(7qE+wVD>jM9c{0Z~So+HPN3 ziWftzcK@*nU#uyPV1UX6UtSMqC*Sd!W~dxoNg`D>qyB&uEMoNGHw$|>j+c?}#e-d&34l*bc!Qw4s=L*-q<$^SstC7(3)uI5O6VQ0FCR-js!;;3OE9<}MYE2Pm^QPKB7VOf&b z^S1xrQ$)OQ^#2KqNfC**rC{B99?U6q43xPr&8Lc1x~Z<7{HXxkYdQUbnq}8{fa9hg?r(}+N7Gz?!3X*|ON)$oIbd|1v#6Yqm9)fchfwlb zQXL%vHwGYxA2l3z-Zm@qto#yJy9-}M1s)mo9)(VU>@~m^mQg6dImujvCt`a(a-jKv zHa2A9V_AWib2e%^l~G*vR_#JdiQEJTGq{oof|XUO^PJ+4fU4Ers(%-|K00;-mON3 zTG)P5#f*9_!q>$+;GVuOkybKsI*3J46!fgOo8`_bfd&x+l>)r%Nk`p&40mymgy8Vm z-inOJ3%boxU?!gOS3;Ap`o;jI)@rphOke%ApZQ7PSRUR)=41kp!1rz8-l#nG_@tSr zgsN&0>v9nLJVL2mlIzr?>lWI=uYm zA0CQp00%q->1x zEY5+)u|XpbZ-kKq`rNbg-SWo)UF=}i`TN=>aUDUQZ2jDxtAi2#OX&7&E3Wzi3td@5 zwp&Cww{sVdbexRVLPz;1s}w!c+9f>^oL#^HoFh#1>o(+~mR9l@4U_GgY;Tq4iG1ff zRtac%jB4IT)Uevc`iB9M2RXr~@uGoQGsPTp#tPkG_<-x9G~}>stcJQ~qn7 z0$&X^ud}@-Exg}TvrGa30aIV3WhkY<5la{lu{byZ&0nl-r^g*W@L5kXCIXAO0ad)OyrYN?Z>CE8+=vmHgipN#6hz0 z#PIe1ds7XDlP?hlmm-=P;~10*u==%PT6PY3m+67)GFpkh;)V1EU z3V>)Me$W-%Mzf4_la|nR8Rja7haw_KH&qGPj;LGB8zi&5j9)5ah=ZCC;bx|uN4wPc zzfoAP2Y#=M%9aI5y#_jh=_vI1t>T;9|&wM4%^hTC!z}H&P!^RqWd1VK~#t9SPOv z5ZojH7Br}KnCepbC$;OVvpNIjK{>KkrtORsWdIlQun=TX0`6AC;2YS<$VAO$QSVJHD=GAF__ypbt7&m|DwF@(@#PITUx`>~mK43Bh z61YlM6k=XIK!t(}0l2J0RTIEml7)r8VJ|m{q1!}|1oyl5Y1YNr6VDn3fJoQF1Y9?`I%O5O*vo)| zUMqN}KR#@O-mx#05l;&TKdDC&@76xZjC&@WS-48#9)aTEOG`7O79f6Y#;**uDcq@| z$3YrWSG*Y)5NahuLi=AoDM_gA&(cH!jP0b*qO32fv1^BLv8ZYOv=q~rEd0l88Zo8Y zmBWCtlVvGfgU**7I2BVjdVTlGu`}}%PE78*Ka62!J|Aw|e>z$aWt5h}WkWh})vAba zhWq#L6A^wro9W@N5N#O=3lyQ>#J~Dh_FchV)7}t36lqn3G#p2Jkw|3kq`uE924E9u zY>RvM_aKIwo^Vh%A>M4Axm_*=mr&eI9Xf;4amROzf{THHy|FxGvqm}LSvkFq60TKf zVP(CcRe|3*spq@uKoO6*W%PV7)xjEyL5oB!;;$Mun5ceD*5VI~-MMvq=${`j`YQ-o zrvmF%$sIbCmtETaLUX969zTaZcTtGQ@+LCJn)T<1k7^S2Nt3@|C`Ix;bC{~vzi8|$ z@usHcz5KZ=o3g8`Bjy|@6h{RRtazD_XMG;6B~c$Mq~|%@GW#GylE9J(<}X0my zf2If-y+oT=42qVRR^Pc#({hP7?H(1RbFGDN(tALO%CM<(S`V0Q54=G%ivSmmVB>g>W5$w7> zkkCK&r!$L8cpPK7?78+;GX`744|9P`TNm1V;@OHQIRHygSZGX(f_vuIPWqMZ;tkXD zV~`8_VDg;~pO-S^4#`To_~3YvqY+-#YIp*DQ5WdEGlg%T`nd0{u( zr6jU5>_FmK4DP5kV^{NHZoF$qy*_4xTshofvAt&vT+l{gZ^zt?AR#=Ca9IE;dUgg8 zm?sDCE>&k8@fSu-Vy>x$?NQ|ZfDt%0H9JtJ*9gcwaMoTcY5oAuininTLkvS;Hn2Oo zp>MfwO1SFXPhRtYe#KY9$pL)#PkmzJ&LSwAW=zNr#>KHl97jQ#3lhmzy;0ymwKm@` z{8?%RU=ZDRWF}tO=2s9YBKBq<18`HBXpz@*6VMtL=FR}VtK<$!|EJbB<>fa$hERwi zbr(4G3koOqz~2%MI?9vBgU(i0F~PxpuX!;&hH5fFlFQ=@EIbdOZW3B}cSr?w@{o`; zt_^iMks43N>J-l^b^^uC5rtQaz-rKT3(-u6B59WQ<~qRPKn5j$rPoBYBSy?+kMoea zoM{kH!G*P~yu#(Lvw37rT`}abHi)3NR0vSZ9Ae;S zRzJT+aYf_9e<-_y=BSm5EWTU=Mh^1n#Vx5BHcbIZQb}AY6zM&q7pY8u9nF1#r9;4I zemIqIOZ61XX{mHu&=^VndKd(0RaiA)u0FgY*x2$#Wp_LY4Wqps)2}ua3Xikv85~Xw zWCZ`d#8&Wj5h~_rCkW3=-@h6aoWa~RH@yFDzRFPKc1R4Wta0B+Ab*At5SA@n$(d zV=foyI4uRJC299^jOJD6w~W`-X=ekD0r?5{giv*hxoL|^i?rlgNQe_UEYjC!xPe z7FAUg-Mp?gjl2D-$7$=k<7+@|pUk95Y@-{}G+b zyubWAbq4>NCAR57N3n3|8rHTn@#SXh=@0>kZ~!mjnI%)$&AUdQ4KN<~W|3ucw>U(=W)L!jW#{S-Qr6cXcL7`eL!^4`W*~5JSiHM`!h5&Up5TK&O|U z8|3%k7{BzDz$_j;R#_lKhk?lE{n`|{M;Fh($D!Gd?OEmZ!^h2*>WH=+utb_*F88F0 zG-_{9nO^8eNT9`mBY{;)J#h8ed#4WJq{y$FbE5$tw~VdPMvYL4kn_02ZJ1n$>(Ky6 zo1sDZ#^~OZU|r2c8I2uzZW+^o{7*+#FHo zuQ}=8rM0aD7V=3M`1}1SU&4d$d7bhH`9YO=$T4XgWo=T z;FN7>+`IlPn#Y;Ce5(4Hxf$8iPPs`jArRkRvEpL~I*((0zh5XFqBEWIL13G@`WZ_C z*>eRwnAJ6?L;Y^00N;ZI_B4ml(*F;c)X!HO0iC!dDE_TE52PK4`;aV&)RY3rr&6(C zF$|d0u#D{ne1Dg36!O_&EJDs{P@^w^idLmSUqGVuziSOOZ=cW6b4VsJJPS}U@a*W$ zqdtBRgAG+1+k(bEb-B6SL@?*Z>9{uG-4=*uQv2kO{Q8-la-O}vH8%?H-@$CHBn_3| zh{M!BbQ4Rp41<-g-&%iR-x6IPlRvNF`%3*-ns_JXJy<<8Zomv##y+?K=ob^VGFB|` zWl0T$U!|u2*{(qP;-Y{@FEj$vbXiDCQJGITtzSTiy|==&q}Fn0qsVDv=wY7fF;kyD zGBl?fPcja@@uwXG`eX~)?%O<=)YWp=v2NpS5|jqCKSqr#*g++{Z!g1UNDH2~54{ctnJ4pyGN)VcmR$c019e7XU|Yx@)m78km3%+Kp`*e^ z{IeHnW$Ty$H;ogH;v|aRO)N;SdCxwd)yz>b4;5k8j8Ox`-hpKzPcf9jnD`Ib#dcjB za?Q|!2)4o-C`b!NIp_^(?N&##-fch9NQ_Z+rN)_-P1ZEhX++!G+)Iy^diI(L{`(R^ zh>N~XIPUH<6nX(d3mq5Mo@;Z&AhU^dr^LXI&O6V?Z)bE%#SaU^?8DTGr{+Q!0pOY4A1i&_2lA>4U;#PQg#;~Ksw0&S8T0VP z9|gu-MH^E+F%NuUk$o`G9X@~hQ=jB6D-lab`7Kn;I_9tnj9;pApli6R5FDUcAF8oG$^ms>K+iH0rQ;x1L)7KBvZMH4fgGtb zKgt46RM5oxys?y*>PDeYK#<2v0B%35@?)>XLp!#UP!vlcLkpE}{y6V}V?Ys=-XIL< zNWBcKeH%y!L1i%rO~#Nz+?h|2?Z_z@an~lNdzY_yDsO1X;5Xujkf39eI}LfQE5ee( z`LO*g^@TfaP#MUJUMt~0)aRw-9CrtchWGWQQt`N;&>yL$VuYT{0Hk|RKyz{TguPBe z3S@Uc7UaB!6VdUtDah6$*77_tlZdrO`dR^C<|6dWh-Oh2ihmWeO;iQDu4h*K#yt#e zc(>8>Wm)IHn{#3<;5wH3ow|n|F~cXN(a!S3Q;#kM>!1BrP+ls}aAmd838Ayqx{ktv zqF)kUoy4pLH>U~srH;qZW%D)!vrI)qK{A2EJl*{&T0qQHQ7SLDq=Kt5t^LP*Fzqo# z+Q3w$8mD)(X4TxC@c+|OO{}Mdi~uyPh-+_Xw5iM2@(bt%v8@j7D|q^T6H9S~{)99) zWP2+^(=TEnNWlizoiB&wyq+2DBp}_MV%f+j$H6Z?*Gh;b=09lc=+8B?hqF=(MKGZK z6ror3HYmCN|234fN^q>#`tmbD1hU*Lp8%=8MOBH5h&K8$1+&>cnUC%1-+z6)WqpR- zch&TzRbqiH0_ayeBLLHQY>S3CQ&mWfE}xs{Zw?g7ZyUnCX74;Hc?+8<-LRJcro!c2 zdT_Ipj{x^3_1_O4wgz&sVJFoZPQi39=TSReor6Ri$|ki5w-TEMsIft?ALPY(7IBFp zh<6w%;`n2J<=ANq)SNA;`WL_jXJt5Pn80&-2WVrq=bT#5V{_@%P^FpG8^&76N#dRS z@*08|MvsyQDZb7`u@?8;pR~<;35Y~%8*F|IIs<>wz_+;s$+S9$X2zM>PyX=fI4756 zYb}n#ok-q}5{ANNNE?y0QL2zv25@iiLq;Ebg_cL>>lJHm(h%3D8gP5aFjX}(bm^%$ zax@v8a%|`gb9GylyLKwex)qm45+@knc8wges?u0LzHLS|4JOu6^L@!5DS*~)W{Vm% z0bF*bWVO2sVIx}Hu>1&|qvNz4W$c0zbyZZLYce9f9AEyW(#iNQY9qBUQ6qW^?;bz3 z0p>~^&(E7A)$!^#5*!7aWvq{^*RoBR+)AY_NXV(FM5O{MS@#eucL93vh6bTydKT_T z1M!Xki4^=L$!Op@QQv8jh5i$I=BYhZLL61EQ!_V(0=O*2uwhR;Q?|NZHd^zWA znvOCjx%gz|7e4mYh}yLj3A5GlR{6jr2JIhob*1DF=pbW38d{{gHnm{T+5tkfJ}nD@ zFdv1|QVcd+24(kvh8Q9>>$b%440<_l3&8+;hsyx9gGiA5kv=;{@(n|cd=Rn63(~Pa z<&z%at{=ljI6qoy{ApI4__$L|+ZkDMR}W&h{wHk!osVZrc5J~+eFWS7g+VESzJwp za02M61o=JZ=Xs_iQEpDP6c%o6OcEq>t(=FxWi?0d-(S8cX($&<8X%K@cjLu6<#~~f ztWf{_3aqbc*F{ZsvAF?Qd5CZ?uNVFw*2MJ{We=K^h){Yl)$-}mwJD%db2x2dtHWp5 zD3|qXl(U%e8R)0#vp=m(PoCk5+*IZ070g#6&t(199$@#Q5AO|YWkI;Wgb`4I)=W9S zeaKFQE2ilpj0peJE-9lI+1Y|ulh19sBd2$MRcMp4cYm#jwZ>EtEZ52}Fzh|fzbs=; zs~EE^n%mfaPYERlze{ZRSMf>z5q48wHiTrotyn|Z9c{t^CGC7l@3Y0&eX7$QU$NIT z^UOv*ct@z2`sH75AEk^5T0@ZE-NtK?O6aU9XGx<9P&zX6@m75OyyQY}O`@EB{XA4s z8?3_^72ppNP#myhS7kgm?#9|5l)SxR@R@PW9OH*ZZ}C)uO(re!Sj5!uf+`R48is4# zv;hyT(8c*{&q~UDFrMh=9lsDGKv<`=QC$4+^tpxur-6vjiHkc4SU1}U!Y3Q_*fOSm{ zO~p$YBjAn0Gp+L>tsq?3g=>qjjb)Nz%$)IbzoOWkm$;cP~Ji%Q3es zUbD)kmR)RKmp;R445hsjTeaWk#6^+27?1_xl!ar%zP&fLRKIxXX8Le?K?Iv%fv>!o zd#J6D%Sp^$$R3{kOnwQ^o~mC>?L^Z`o|sjciFMrPKZfyrSKAS|-B!HP-XnDWhMgX< zhvPzQeV)apNjH0|vR`yN%rk@W>0@t`v8nQeREzQO=qt>#a^bc&jK8bLqLtgpIF*G; zEF1v&Yim5fU=eo`lS(7yQ$UNguP5+uTYGS@u7qsa?Y$8tN&-neQlu2Lr7!z1^KZvF zx!*7Bo*smIK39#cX-<)Xf~z9CuI!muxsuPd;z9Yv#wAVQW>T7%A5O$zm-0)7m>hTs z6*g`!3!hLqMDE3M-w8~x(kEiBzU)|$FUjg1cS@OyfBUZM?bX}8GEgcGNSI9gEDg7) z%?w!+ivX@VaDI;*_9Xwii%p;AlP!L`4v9>I6l3+SZcSwXPLE?4j+L8f zG!S+9EcnypN-ufG=u@=`ucoi}0q~vi?nX@i3+bHl*BqA&rM+1Z(tU4912{Gcbmf>A z%_$Gxba?VHo>zJq3>eh)?CenD=eYhnGFXM#WBic4MKwW`gUmvmNK!e5veSB<6OR^g zFd~YbtQ1udY-PW1AGpB7sv;|cHvC@OYgSz7s#xYtfP*Qdhi3x0k=5%q$T>OF>JF)a z0uHS#wFSw+Z<$+}##*{R&lWgpdP_VsLT}RE41ZUAi`_g z4=4dJLD*Bn(AYvv1H=+|ZX^>S>&XdtemP3M%x?Jaj}7}t%#pI?$#gtEK;MbX2^L<; zW$WgqLU9*A6vf0VsKoHn$n>SoMTpta+T?WH{wtO{eMm^QuvSm?Gki;l;6btGkZe=S=Gx_uE@QOGGFL7zJqy~~?YoPh9lR8~A zTwvsPBu_xLx%vk@zp@d4wJ*LBj5U7~N|pTYDDo+OCJIJgX9zJ^n{$w$^Kl~L2P(1C zf-O1ON*pBK$lvUC`_tzZ%_c?DLVkWR z<@`4u)x@yVEI0IR^8I-caugQZn|7ohB)8Ptnjtin#3Czz7B~`cg^L^fGsDl1%V{oO z5#pe|JIb4WYp{tsEeyp@Fk-hd-KA81k(O_LMHTh^1#%^NbqnO2h%P|)qq)8~@IdUZ zMWrBXs>WE1Iq8OijUHl+cjCKpl9X;)R85>7K&VL^@ z8f5`=JDL`oFy%5ahe9b+&JdG?G_&7#r=M7xj-$&5TIBSEtDVV`RDU-@(PZSzrGhEdw~>v_eqNF|&uh?_Tffp#%p$;iKs zmPJU#_EUx_Q0ki_zD#aATPFP(_$_iKEMNUCkpocgGfQWJMIx00Ea@U^7XLP^D*d$U zr=Rum8E~+M+aup9R|IXlf3Va!>d1&T+wHK$0{$4K-Y6#Ox|y$5GbuwT5fJ31v?Znv7RpMg96Y6Wb(jJ^h;KC1-!Ai0(%#)bk>(9zv&U z>m7wnv6#Y$GAZa?dY@a^c5N_xr4tO}ftxfFvPt#7|SDL)hEv-rmNW?*yq_+cPspzcPO4VKKct#4rE4 zUjBc1a{*Z4&m-?7ft;$0?e;x$;GN8z;Qp%f{2 zDDI-F-Tg@$qqY%CJ72k?eqW}!K<9`=g05DIi&ow$WMK;>u}T3ri+EQ9I{!K><%2_l zbr&}9W<$U;sdkAJB_LX`_T1mZm9nGSkj|2OjlmJuK!_%j*xdx-A*Y{Yg zm#_U(3bK&PvzUby;I=t0WnJv~sXY7`b_^>I70t$e{Au_0D8yUv@S8o2Ycr$eN`B5q zt45A~%*taOF4n1ab~W%-T-w?aW$lniaUgnej|{q$FNH`fia^H zE05#E!jWXyqp}>;I)TG|TsFo$l3EgLukJB64$YXC!qUnaa*h2Ik@!HQ;iMvgCL%lc z<*Hcc0Wm2*$d|d#x1#kXXdxMEmLDdpsG1b*Pv{i9^G{?&-tkokJjJvdmlGgTrW9+% z<*){Yo*XM5xBPtQ2wRPS|NYXV&+_u*7iH(NSWPa#DSD7&4)>|FubDG`Ax}VrCNC&r zj7wa-7+Q3)`okaIlM)q2zRu-s3V&s})Y|CiFgP&m*)tM%2LaX^Q^PB0x458rAM}T( zpAK1x)k*Y3Ck{$$r4vidCOeIMkVThGyXa}_Ls&W9xdJV=QRiRI|4txk<&LJ;Dk%A^ zx%jQU2UdB0oSD;L?zKD@{`j>tXWa4#C-9(jl5D6Cgj4GpiJclHrOfFuJdT;RTCBri z>U`0*xw3R`IEFr2@%k1O8w$A0TPg$o8mCxxZ~;mn7f-FPyi7z!1XQ(Bv*66?D}`}n zR*SezW=u_nYBVOOmlNst$A(@L_8R-hA?y0K06taxt)n&jnw9}@UIJ_(fGJUzM_u+m zo&WxBj~tI$@efsR)S~z7o$R0@&43B7b71smxx*t`Y?Zpl+ALB?E0%nePA_JcsQh4^ zw4dhJ7n^`J(@I6nua=OXqj5nQTC#qW@^qheV;{cpL-HCHd?czR93f&0KoqO|bNE|{ zl^v16D8)3l7CMW!c5HI>mmIZ7EPB15BQ}dj>i@Snr~0^^rBHSnBWxLaK@xtND1zXA zcWd1}>1erYO%f83A&9HLR{=vTLPqFTnuH*fK*lyiABpmcF9UFeNZ{i!>s00RWf~t^ z1sl_9Rp-5lO;d(5_GYzAdpGuZ2^oh$=>O@Zbw$j%(A9-( zty+H`fD74$Aqh;RqdgD%7@JtL4P%dX4co>|2iL2)-X@-rgaZPWw^oyHE%H}*mYtFe zP(v{sNe9M78~BIx;uUy&b?B5M`;xfr+fAFpKW9p;t+)7hvwPm!W$_TYe86VCl?@N! z-fiY+2MiBWH{}w;63N4C-R8cc-z;Tw%elX$>;Fxsxe-gz<~j?-cT;egZn|+GR3`JG z0}V8crTAvLx192tkJzf?_=2p30_-Owg+qOmV*ZlA@R==OyQfS98uRO7rJS&z<4P0Gfd&h z>>jPkqPETGuq{iJ0A(RlKC6T8`a8HR#~u;~Id$#4n&_Nw7(h2YbqU;=r*Oa%e8Gfn znGqXXLCT}>N9dM5%S0!jf!uG_B;H@-zm9+hda!7-mEMOYYlK?R+PyfP4_P^)C~u;& zYLuwaf}(6AV>!pJ`nV`po&QY@Qt9zdXZSo14pmbN6PKrrg8qS{8@)1ro&rO$(%+6M z3jZ1iSU}l6bH;{^7F_Da1DLjhX0%`bFJelh4F{L#IFK!hda-2 zgT?yJKh;!B7;k){pY^uNyjb5w=UN1@`6RJwhc|DO)jt_{jdDVNZk@Wa1WPeTM)g_b z3nCZ?Jquxf^Vpo*^*?S^5m91mcnY&qcoWr5=t>d&3b_QrvIh8zXLki!w~NIO%4V*! zKSvuUnwWN5uNPtk-Rq4RoG;WP?!nDpc|vaC))M=(hLfnIUSA^(aBogoA7aH2CpwpW zT(&_Dwb0>AciW27yK&IvtNIuje`Ow-k+=0GufmeGSch zxnh>tjic=>Mr2!}ma%jhO}EXTSD^v!>IsZ&bH4M=OJ*YqtavZu2m7wEuMJR|!x5nt+Wm$_d=<~NKGkona6%8y!u<-d zG?_?Q!`hePaqUKL?ZW3+ML#DUY#nBMrbbl6HXADpR~AHsfI$7Rq^miUm3ZULuPfD? zyp9IilWK@Z|AO$wBcTSxjq+{yx*gY+v*44zo?=G6svSPJZyYLyyuAToP-d`{u3&FM~hJ2c#*L zLLOu9u#lp7(WELWNazz3vs}IUfa3pxn#u@uC%Mx-yc3UDwikuah}-p0P8c;9S3srK z)`U2^yl;g2+W5$AeV%gr+78%0imX~6HlD2Sa=FcYf8?OyO|5b36?`L`C}Q@~!QDHvmfrCIR1oNeN= zF?6IM-X!mMM8vkPfPqMCuDW26yi7x+eVVNe&EUIn6{CRupEU4{`y5F)$%OFCP7lZn z%l95{W{H|trg=}PgyZWFCW%W1?2F;x3HvIKm40j&cOvDtZCK2~%y+Z0sAikT{P<7o6!UeDa7 zC)M;sqG>&EaJ?8!i1505HA71EPV&KTOKz5xxm%!^Y_POktO8Hg8Zl%9E!jxQ0xsqAu;#0~Bk}fzOU1EW)hN&ldaO}t)rRK-(UfHVbGP_Ss${Voy2Be+6pYIdbtHpAWYY#UIu~!JK%o zSb070SDe~J#tbC9w_1zo8b(b*UQ0(^sU8QoXjYf84WW#$hL_6;3lmdYoB=RiuSVBU z;0}3VtSh^T{U-TY%A`)`B6&2stYsM4UIc@Ce}!TJjTP0ycEy-o&^^{Fa76*;7^+*w z+b;SuL9sABCkcL;wb#^wN zNWG-~KwrJ3y!Ei{FO1xyEhoi8LmY?q1vW<5Fwe0P5}r)C6Rn(s8&KX?yxYPY9I-HG6kc1~P<$3r{y5FR^SD`{%0 zvcvHMlwk)&l$voi$#P3+^1HKqs~)RX#=D^L9&Rz%e_l@ZbTYu zXIuec)1f0Pu>2T<=lJj+6-4^!bO2l;y4}@a#nnz#)f%}B?pT{QqM;*cEPLBIihj}G z3p%vuqI<<8L;GtX9Cv?1=pi5~#oFE0^|#l>z$={`wEYFT<+*YgWA6N)?5_v z(#?jIqc{9`P;wAU;G<@JYqQA4aR29R7Jd-V$fNa21Wy0yHc=C;hO8v4 zf%K(z42I&xGKQ{2H<^as&*iqUP+Q{zlec$24wnC-@#wBS9C9D?qdxy$#IGNYJNqJ!YP%tupn@3@)*_0@w?xYp6fXgSqh*Zaf zFYdw2%$VBk8=`}lndbGfEnyj{o5>c3@1XXzO2Ohsbq{b~+j_TFR(a#_Ebmo=?v9wD zWmGBJAoXq@8{Iqb@*>beYq5f63?}gX!p2?Kx>@lr;`3oPLj}B3CW=;4Pz)-!7`nTM z{99#XmFG##T+%mA$I1iI0z>0!0bVaG!;Q_zYB6OK6m)B8M%^f@cnfYVgc~)T=>ROc zF5jr%N|sP{jqv>%Mw<9253-Yw4q~-p&8KY+49q04V`iJP|P7lbo#TW##RsQQC}NpSoqh{{9@JC%dgUAgB4T5+`1ymreCGh5TG8w(0zl z2jPhRR;T2bjE-blP4-D&wzq&54>tV*^@#=xg__a>cgvvOo&u&(w@bs}#(*aWhA!B| z&+LeLcs=%XWf3D5tU~Np8k0un+%YW9F$}Hwg?un2Mujqa>?v-q3rr+d8;?AhXYnvf zKu9ll1Kg9A1ms{tW7A@2$(Fw3HUB5N1hK+Fe%4^$my1>Vl1CCHLH6}bbF_A^vi;r= z&w+1U#Ow4XUf2YJ@-ENBCjwGwpwr;N#?c}P$O~Sg$WGl3#D9bG0 zID*Mk;5QOmHvAvCB?I1AD3A;qmN4GEJ;Rw)4Xgl&;mnjty}^3kTMam~yOIQlP&nFa zTJ9M555mY3UdjG8Njh{TqRJb%&XKd+gjnr5(CF{jm~0uSb9R^kTuM4y^QJyX)mf=- zJge?^{c|VkbKw8}Trg`<^Dw@1gDQ$W9R*Yn&8KW%Cc!p4K~$ zt1-!8Q(t!?*oTq`9;sZwz#Pi;i`L=LEGY2R`N>W2A)hud%K1fuYNNCN7i?O-vEZ1} zS>{hRss8A(VVh#WUnxd_{ghe{KFr-A_BMOf9BGU?Dc^?S_VDgPbq!#T=;y!Y^xpx9 zJuZ+@@#<72Tdkwn;L7k)%s;#}>-#nKYnH2_INkXSyMLlcMYGJq-`PA#f+1)Ux!HLJ zpv}Y;*GNj?H;E6Ab&96(g{kz^3)TPi%~HGh*wmiWDYegx1>kNw_ArgA9jg zw>qkQwIbOK*>^yElrRA~uGyIzR;&^J2y z7=Ew%W2$0LnDFd%UQVgVcM}mxo(KjuvI(?`FuVXhFn_9Y&scB5su8f3m2%fN zsVETRrHabbv2WB?$*4vi?s@ODP?Jgyx4(R0(twgM&9B+KvkA;zOZ$8+HMqp84U)D_ zRp8Zk*Gn!>tO}7?VW0!9JM0ialDbaVY%WMFqNgtRvgB7)t`aw%Nb<068_)698-63f z0GLk>L?5`BWajn$5cpFah-Q+p1diItEccy0mtV#AiTYATybM)MM87>7zZ}r()iYJL zfQ%!RlQ}HlKj}qFDZPA!F#_(TY4SCsJ1%maYeQvSp!MDrKJNQg4=Lj^`A<0SbD0XM%~M{5xCa;#PZ!YU2;sQn^tm0FkUXG7mvj8^@9yegbA)74@aMj?_R zxYFauAWuLrFifsg8GeY;W7ihMGUAHvqZsE$#;925oEz-cWgy7y;$TPS0`xno<1;tu zKAYj2avy{I2iX_FN1?$`iDEfNopLW%LdpMP?6;v>ZQkAt$V_e#Q)_U5+Ry8(C{=iS zDglQRbz=j_aA_UFkyI9~ePj3J3rrDJFo~;smkk_{cwrqALZ)(z%es&<|@Ej*f5U5wx=J z(c3U=hGe6@JhoSRpuWA=0_ksO^5y=t@t#Brbw zmNe^_&FyG@%|s|fm5peXc%e_?vSF%Y<-|JXrO60G)Olsk9Y)%humcFBt9Dy>_(8(9 z_}U|s014vg^dnXg+1F`Ad_T7*u2thShk@G!btA=-B938LPk9)w042I*OvZo{QGCt3 zuo;LGs+GXPQ)po#G`=x~3;bC2V2XmR3$=}-R}7j;$9xGi#f&WT$mba*-HSnCNPJUt zr`uOO3bAJ`*!;^Nz93x@5sI4IJ19+eAx`Y9{jzz-sAYM+37e*slEtYxbCN8xO3>P8 zCB4)Q%q{JCgHrZ6nrc_|i(jE1hQaOwP;-5X>iF(Yn?Qci#SMmJQi^SB?vqwH;rl42 z=uN$6^d9ttnPz$nq@o?gq%;Jg(VZuh0NAk4Aa@`2dLRDMB*^&&u0xl!JEIEFpa3ck zVT_;J&cw3pZ4)QWn2V6@(f0j>K2Six1NIM7N58<>st^WK57Mcw(|is?$}F=9HQ!=F zvwxVmOpA%VnIqsC!1Kh7>T_AQ0e%gJ{H^!Z8VLLXV@g=0pp*cs=C2uoQhLsJSmK&Ni$}@}KA53U?=P8UfoJ!75>n!{m7i_YQ+B%QTd4n6P8#x@ zihrsLzZ^+2zWJ-nSmWV_m`Uxeyx?@Vo~ntv5)ixHTmyaNtx_9z0P?q9{h+>cqhnYRA)-QJ;sg2iX))s&PEaB}YLWlM4Wd7np1@WW-rb)5 zDc%OS&GYEduNHyDs|)3GyEP_ay`-erdK#~H5OMteDk?ZI$8>8uW{6?d^%{AElir$1 zY&_4H?wK;xAf`o_fIR=#Z1YJ~3`z41AMGV;G+UXkELgF+dUOq$ep1mBcD0(eK|hXm zl*0WDrrWG`qfg?kDbqdpP^Y8+3%qzp4r+<1FAUl!q5Acx+tm9s*jbla@55V}7C?THdOtOuzk z0^!8~sJMwGtR$;jJ+HtLhvOyI1_wnfKH&7I-sOD4JtM6#eprOt>?oLNYjPhZXN0}R zXNnEZxF?Ls7z~YTo9|kM^~!XbTb>=;telC@8RAJ60v4lQN`n@9h-QjEiw}dBNZcOP z2{jXqj__br0)Cp#keApZEPFVj&|_*c$C>?8$kK25dk$roiBySf3MlI=f@F0pdsqS)tyOk~Ew(Qz3uF z7B@4P9SolXtT*EnB0YWP9%UtDG49nC;)17(ELI|<5@Rc;|4g~RPUA)XZ4^=0?@H_D z;&QeAOQhiZHtw-$8_iJNu3_4FKYLLn6QU@K*f!076K;5wHtK2d@N}r#11JZY6P*aT zeE}+cM$2_Hcs4HQ&pWPz$L3Up@|EbygA3;v{tN{#`w=k&-_@A%^Aw_NJrnTqcG01D!Kpoj zSp+x*K?67EHl>iIM|ej`*Sgj9*}vB-15I85sf4Od40N=H^X|F=X+hbcWRDv?oio8Q z)Y2)xW_nBGnEQ9);K(0o$^2<7iYUBKYHc&bgVXyWiYB|qQw0u4=cpa&Q92~*0S^@q zD*y0u+zQHM2O{7Joo311Map4$qAYRP#+Tcy+3Dm-7r}6uXUh9 z{d|-3JcfI$PuhC_;$F8#v1OpIeax6B1RA@wWl=B*U`pcUZ*1MGvNvL83&`$SM>E!Z zSjU{`cq)Ds+VVUJV3u?pBxT{R6AJ{WlPKZ&t9`!;S$WH0hwj1|Vs}t&($Hkc2)uAW z7IgHV+?z9Rjc<71$yn@%enU8&-I@^fL&?sK?j2f12&I;?Qp5COF8wTtUA6Wy+aQj# zj2p_M9HLyANP%WYbL(83)z2dV3v?gY|MYZkL_#2XSQwq~6uwqQG#=+@9D-kc-$6Xc zltS}5!0)+T=5z!tOb>ddqU<;Tkv&3z<3GRe5*Yk%0|mPDi}%e9?>m{d2Qm?-%C<60 zSv|O|iXJ=VEpPNnw8OKqC#A9DmV&`}*A{GEk9FsQt7JLs=S})@4Gv^b?E`PBe|Fhf zhedgSSrgxrDVJYy9fuF)LH)cosB`q}_ah=QG6MYp*F%UJ(cnXCpfsUOm7t9Ra(C$H z*-MxsXphwLdfEwPXlT zdpj|whe2Sv)ucg}0YgOO#lgCpnlYhJ|z~DhZDjePvJc)9;vZ`Q^_ew)$!u^yvL6YI`jB5ymXVw%<*16)bg9Obtgxi$H zq9oCFEsgp4HTUxvU)ILrSQ<1WA;Xa#`_WQ+H zp4*a8SSa<~Yz1MXnJ>FP)%hnMF0R`uWpDLt z>4VLsR2~{So#+ttu@b#_oGO#~HY;}AHV2(L?35Y9f%03S#CQA-jQF%ax zWq~n7y(}}~%pyv&MxX7;amz-$Zc5=WoX|#Gm#Z*oiVH4zXPBzC+or1HyZ2DZgQa|S zNi9Jkwj6e7ih_s^uWgj&dWZ>1pz3}c1ThnbPh*g~jj;5Jd&@pEkNg!Z&=nvKmaAZ- zh6epWrrE?bpe}UJXSP2=xaNi4Jl=_>Ll<|gzToJYS-0-QW>S)WflATWG_yJsLomsZt4QC0=Nr}h) zLRVJxGJSSdxg?iWZOs@D{_3L5vt7Lh3vL@Arop|BDs}Y;2!JVq3k0d}=X=|+)HR-; zE2!Xz28Il6Q@3*7tq(lbaTr}@NqvaF#X?@yVHY&wmPI~z`e1l(7E(JS5ux_o>BLnqE2+HtU zOy8e#CAji1{~*Xqzg8Ua)D^2HHgMU~Zyqd^HzDcCeV%YvN?pL0&5uFen62 z%OHERM1)0cz9b+4V8qb0pzKg1*CR%d-E8JHC-E=$#YCep0U!ZbG6=p*V4a!c;_eAq zEt~j>2}B$JS|B`cAj4^%KVngo z4=5T4FbC}4hJGnh>zmZm*-vZBIxkY+9@2+)REat7<7(h{yQ6(7P}JU>s5p2H;UaP3 zT7hYM=t5#M3UABB@ z@&$*iT$x_I$7V_H+*O%Tz*zDs_$;zSSn*rk`E0MCHK;F%EGW{v>a>6SVqa1TY|0W< z=l3FOyhO3qJpSd?8*2jk(5e(>l}%@ho2?M^MK8nrfD@t9t_-s6Xczo{zNGn*4=AENb$GT+6^ z>n8<}=%RnnYdFnmHuN4O;3205+tr6)N!>c^)xmfF+4JCKAEfgHa9BB!PrEX+L*Nar z{VH4(y!M3eWkwcrEwiSjRVU30eG-B7+Z*rO^_SK(ENQ!IJ%;tnK3;lyt%DKdGkS|t zDdO;bKU>!+bK5gSq2J%o2Nd4Srn7O(#@RlayM+XiS+1uIrs)nG&6UpR-cRTI zjaZzyni|$G!w1?ge#wERsE}8((k(JQN!8s$f!q0XPjV;&EI7=WwJ?0zEv5r=sWOz&~Im)0>vQJD^ zSaQR&p?rZ~c?82|HE*px`6ZLH8l2p<#9DDztsu_6%rm~x#RR#odZ#67I2F{j5ua6G z=vT0R(@JZs5p&_a=vpm(vtoo?X~Tb7@6Fz#5I?PNVcSw83L5uTDbUnq5JI!58pe7g zeHEFMBfZfb@hsNAaLAjaJ1%5KSCRVH7LbY$h`{jmo?^O#v0@wTuF?O9372CFKas9U z)*qeiU%h1k-5ng&zMl*Fsd#v4KtJ91As-6^GKG=~eJ9{I`j0IW6m2qh_26*?pnu^V-t>1{<)bzA+0h7OrNoL^v;>~P+`}SeNnf!) z`&NcIlxlxy*RJZI)nTeP+{>fPp^v7#6SaetHq3Zq;XvT(c<6d(&1Wikm%5H$xfKOE zC$jO~fb<3U0oy4(`<14e4fCe|H-|&Y8`X@8y6-ku;7LT?+wkfSJ?ILvH8^Uo^b}M7 zF^3~ooF_!*WP*|@SK~GF=e0AYBl4nV9Y{U8OjTz~<@Hjspfe>$MUT(l#W%T!!Wa@k zr=L2bU9!DD$>Il4FlQ;o_k#fJ4c$7&*mukD?xhtl1Iro{%S9D0=bP%*6*#QCoJO)!**;ZwbHZWuhjtlMEi4d=JG{do15vse;ZpFla!pWcgP)aaN;D zL(EYSOhex=BveFv?o0IQ0R$*j;hTbfYy1BIG}Pcb3rS4%o5(we=OwK7Hc}1JPLARG z2ZO(vW={5??p2Fu)OE%f1G*^8Bc@iI^pzO&;*Yf>Z7%O#P+tq@P7R z%&`Uf3Sg#LIY494a(rkIM7x7nY$b}0n3-TG9Qu+;#$@ON~k~SfTu6Un~-`rdON<1#V6VEtqqNPOQ zM*E0yhz*WQ>Qk!~(aJ#CCtaw-A20h%8JplcKs9vi5`D0Y>XPp2vX!o{BVXa0H06(-OK3L-j32MBGX_uGB1xU7-jJ z=ReQHW6a&}nzGycH9W%u2(`^cPvj;-Bz>s=|F`br>`wG%ohw9^D7QFwIMcxw0Z0~4 z?ulDg{a8E7r|G3 z?NRSGVUjQm)*MrCTy^9speflMcoJOt^j3J|3KwyxfX8+!Zj3LZfv%wIZ>u^v$?ynY z3Mj=_wkc{ZC7I4bY)<-DiG2$Nd;1)lJVb%YCjW%GM`7=v@L9&9DZ$w3 z_3EGmgkO9IVkG_22||8Db?AUL@4K~#v7~lUXc{n&j79!-0TbtT{)lfy#p>o_PWb$H zH^8R`d2vvEs8Cw;8cx9tslwYKbQTr_I>-eTqx*=~Ndep~xbgVMoK+=et z8e^;%0;Jo8*1Rva0x4>r~H27e(U_2nJ7ni5eiFtW&HLn)i-58FET zRmjm&wASP+f%JZdH}NI1vd(`I?6(0j@Hd9)m0}GF0(zj2ngG_&D|i`@$g1wrnz3&P zqNXain3MS}kIJmDZ`p7&{p2+BaP)T{W))|0(g+*ua*c077#e5h+;J|308s_L++g4w zbJ%#SJ+mZ>@+WKzdM+ZPBF+c9Q!l%>(tioce$+@&whwl3cQ>VuPg8(P94aht;vjIX z+XY0QV~dQ|7&tWXJ#&Fpi_l}nD*~iQ*ZvRwZtIr3KHYAmg{2GLA?Eq(g5><9>% z=f>sO35M~tUVSIP1@k&|@6lEMj7=H=>*%_|3|ZF>3+r7!hL&P!rMIrL;;t77MHgv!O&$r2|ut47>PfD0P(yl3Oa{G^q z^?X<%(W4p$=G)OQ{@Q~Nqs$K_GRp-#Ad|c`O7sd0V6{QG*W&IhMEM*>vxyNWM#18i ziTe?r&f+yAo2UmpC1sW8;bq_)EX;~wKJbvD(QK_gJj2ZIMFq7a}?*tLb5p6`w7X z9`s0Dqh*_n0WpwiE><*w8Cg>U7nY^Z{k-MDNzE! zqH!UfR+@acfz$PCko3CKQX|g35*bAt9x?xU|Rh#cKQZlTyN4mhwh!8!HwZzR# z!)pTZx|*vXRJc$2D{BC`dyp|>L~hG|6m9HeW2~>bCE#uhT+WEN5d>@k+$=HO2XcYX z?7thd)5?PdspWbQO-nontOIWmzmMA>snj%?s z_MeAh4cXhoND~QW>!kHF-2n=rzT1`Cw)=@lYst68gu)-^AOV^=yGwlF?vMz|+vn1! z-hXlq})cXcU%?R@c`G zxUX(r|E<2bz!!@tLmI4+CXLBP``Nsgrc`?DDWIJ`bq~R@bXU2@H7``49W7a0*H<;6 zWZM#(WTtynszD3G9&WS-pAONZ&6}e!DzSPXe9E!KyPK+p*V%o}g4Z84L5+Lm)Phq1 zrtuUA{T$da4OTJwZJQB%?VFBsPPvwmEdQHSByCXcj-NChW%>dKlD~e4<8vOo*o{mEm>n8)-*BjSG^x!?QgKiM-K5E~Z1PkFPcHP#Z9^gvovBWFG zVuCk*<^S6ct(ZCpUwyqIsV?bh#v%*UZ!kXq*U^sDev1vj=Vx+2Of-Vir8e z2udpGFu-!{B{c)W!p>R^0&Z>lI@C2rHnY_bEGY{U)&5mTwI$ZoHoxFdbv_I}$Np~Z zP|j~}b`l`r5Vthdvl~#*iyKVs;N?3QEd%Yd5)yCeBL0=-vkm;bcgy}6fiBQ><=$(v z(V@8LU;AB7e!}ITMyXCK=Qai}-med9cMlV^k3~qs@@iPh4LM59Zz#d41YyPX(w}df z$7sg?^hG2{FYEIp59C!5p&6M&+)ev5MoF(uwh&*@NVnGyQbjEb&D|zkA#P%U$MYF& z*)QSxC&;^sq$&~AdwhAhCsS}-ym;D1%lo_BI10L;&v$ft=b~_Q{Bo`$Q(lv;Nv;nGQ*boD`U

6*{Zocc% z3T=`Di5q&&Fny#WA|iG|?n zeSz$84~EvI64(kzo3oiK(ku><8j0;BNDwDH{xL1i*YO~B+-e#sZ!d>I*}Gu%@0#_f zhy2vR@xqZ*@)T_sq$A<*g{g#qgqx}igLm6Cv_`lQ0gB$muz53z^Weckzz>q%rdaD& zRZSdd%ib!XQS_9QY=_p0Z>lSoI&JB6gMXkk@tc)qRZ7dWUK-|>0dlqIVFhsX)k>KF zsgljYU@hd0zDrTm57?ZDh6R_~g-T3fX!KowMf!PA_}@`yu%jz>b{N~h^_l|QQ(DbQ zXdE!hWukaJkw5F+1qH%PT<+AQcjcV96t{W>Ug?`<2uNmQ*#a%LNn87=d8$we*QAWi@G-dtJon)Bq) zHF9-7_r&OFRX=ubNC#oxah8$|x^?mt0Q){<^)+!n8&qwI{WbiLB3@)pit7yXHU1{0 zqJ*v{Wc}UB6z~Z%il{2>apeO&YP>hytpiX~NY43proX(cB}XS~N(cE$*%k3?M8}oe zyr-`C&Sp#Tw?-@B4SOrwt&$@9`YIX)o?&y`!(_MREZ>e^pA(dG;s2#6A^{g*$m8O( zy!=<1Zi|CKzv25qg~RmVY*jD7O8A;5olYB_4|}mTVq{r%Nhl?>rp&9Y)vxW$(g?O3 ztAsM)I(J5{gr6c;cD5tkWfno3St-#6=RxC0RNIz-6|h>Rx%e1!YH!>{0pb-g(5Iq) z_mnV}sv^r`2hQDkUFf^_xhgc(O;3aD?x?ZcFuGDW&L+Dy2*qIX^}i)o!7pPkHOuR$ z6KmYoPrf}&8cy@HBxA}j>Z&edGIjiV59k%p55ZUb&qb0O+X%Kh1#+&96{-YWM5p_W zXsPDen%XGk8%HN#i9fgfN29#0^PNXk#L-rRccEm3omXCTk>5cq%@h+idK9)H0}Ek~ zQ#oMGY{(_U*S{4WvoX@gNkh2LgU(}`m%n$w*oW@5=iTB;u%`e$K*GOlnHL{y`eRst zY;n)6Wrf$F89b5RiUAS1Xf~H$*GL;3%{X@iq9~Del~aA>Rs#hOf#v0sPqc?BvUhL6 zT+`bXihmypL3sLD;*HZZ&CXa4@F!2bPab5IIHYaMp7Cw@41BGE^Hy;Mc^b0-4?eIs z%Ao`kmJ@m184&yqc*B#UH*pfo;_R zao7~^%h&3~q?SRNI2?3l`u3zq=J57)kQiI5ywbU#Vi?$ZkJc)q$mAR|)$tY?!oN=y z(Lb+YxxSpWTt3UxEt)7ani>Ao1LaW>fJu3gbTYGFFRoYQI9+QWduZN$IoxLLQytil zA`ez*!gkyjolICxLy^(*xSg;fuFP+oPz6m+dio3wCZ;o8b3H*7@VfAU1^g}JL8Gnt z!yuma%dVON!WvSXDl}T8G9lO9W_tjKKcyop5njJolv=*JaicNdG=+g8-mD1b%f{jp z>N3hr*a4YVPv%=EpmNAs1^uTl75YG?JP*ZRPNQj8ZOiMJ3Zoslf?t>ZMoJX&_5MU- z+YNP<^!Sr0@Qs)w;ILSAVm|T%Rh76PDs-xS(=MjuXLe)sdz)2HeB7^eSJ~h%0DC5mbLSCm9h*OmE0Z~r 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

#u84~JY)U4#|OL12ve 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ⅇ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

    &CAvA{?L~*^C z+BZq^y`Q(qc-1~M|_+zsar3-K?xH&8!}uTwM-?L4Xx zAKm+B)gcLnc0Zhm*og-6K`Z@N@c;#3(HlTuIpAZ6|K@F7+<7k8G`|})xn!|ix|N5N z2+=tq2`uI^eaT+0^Ic-f!hMwSQ3L(nWwfG&y;SceZE8Ux0o!#r#5VAgUnA}#Oc*X| zXlUGX;l?I^O+xs{57SBRt*25im!ViM)3Q!-eJMn2-rUVBJ4-uP!VRR-7c>;VNqqC) z)Z4x-#}^d6fl>|X?o=yn!dw^?>8f$7GUK(w`eC@&q|o67yGNfXRyV*rm?GUDQ=MF8Q{bM-dTXC&^x{^GEf85U&01#jXDw4* zijw*dBfQd_*KxkeF)6%A4ZbwWOxv_|M#6r#jYFWi=rBdUlooJh3RvBbF96R?$_Owf z*Vg_8VkRaXit*3brv}J4^DUgullpD30A{BNUcyohcdW!YHbZU|Pt~;$?W2sl6{uR2 ztmVIrCY0l1zB}ZD(pRFrv%$oNL3b=|tH5ot|>y#IO6xz$+n^hoXR?k4B6GUhrwj^!`Sl+{1 zU}6JZ{vhFxU_}u3HBV7Jx5#ZUwx|8FOW(8&&H=Utnm;I-iua@b504-&oW+tF4*BzS z%kiaWVwlW9W5FD<&9aQj6#Nj&q8g)vtP@oH2d@?^ufNMFyXqVz6E<$@X*Bw@GHwb$ z7>VHvtM&$gmmtP+F;&5>&}jy?S~c76rGp{&y4}g0;a-L%y=UR;!oYive&s6foFdqof*xFF;RfKWTKb=4UL>AJ?$D%o{cX(s)ry0Vz!`v{N82c7Q5KOaf~4 z0itdyKghD?jL1FAwX9>T>vOB*kTZKoKq>`OtYeP(2jvk$Xj_3zjJdwDe&V;Qf0BLxh)iz4&m2x)iY zR4$hPjq*oCw_lvneR-KMu%t^&OS8d(GM9^m3T%?%;#p&eb(!q-(&&D;V#^>22wgYj zP^>oqD~6usI}dXLXg|NdVBno?05X3#B7mPXfG+=;2wrNiQF0x@*6;L-`x-S4ZfFz% zPk5oE8g-YnQNgD<#HO34j)YePl|xYlczg%_54w8R*X$G;bLL6k^Wpc_&VnI4#V!q! z8+@rwp86pR$AZ%-US|{95le3HHQ*+??TM=3S4WA{{EC%c?z7^!@}4WtL$scL{kws@ z^f=jRlW$iTz8QQxfiAHD(OQ~m(biyxI21yWCy~V6nK$L`#%C!*l6@B&%a$Gm2TX_qmb0qKa z^yTV2cDd_rh2o?0Esr_+IzSgt3MF?Oyi0~n{i#(rb$+j%@>tF))E(z;yU zrqJe!O3ryg@BKSZa{hDj4}&Yggb%Oaa&>?PsV9~Ii1&7EcH5e35NSdJ197v`{MN`b zlBd??W2QoE=2x7^c>gpxZC-P)Oi3*zMK9QXupRKTAbzXk>m~dudxCSrULbKD7^I-i zfEtU`4NoBVpem9crVGE0=}0e;g9S3kJ|S1B7g@2#1~i+fAi z_Pw7MY|Ce0R6b!UUR2xK@5Sk8{e$?^4>rA1lL8nAZ_I)XhHjWOAPomkdbKjMD}#xv zQN-2J;TZVh={{J3>DiZRA=BPu$^QWylU!yhk5 z{RIxK3^6I0Sy+5gYY3C=C%%00g`?lOm8Q%<_qH^PiGO23B43fVNU1F zI%%ldW2QakY{Lyfr@xC)C)|QHkfpa#%pw~aHH9(@FFh`<&JqX9#Iys#33yQ7--&At zwV-v|>hU?Q9%(|ZX35kFq&iGbwdC4x3A;zT(qR?nL(?F+ z=e9L}bwg5T53BC3N%KrAu(whRo8jLs0^PI0N-!eWH~PAqqBSnK9VEw4gRS;kLNPPc zHJ5DrS2Lb!r;#K+ftMkQw%l=siF9r%6~ok|-R9r{$9`&*J6cyme)*nb929<_MU8Zvw6!wnSCqR=eEB61)wy(W=+ z?`K8fxHJFcA@8OMxK8kId{Oc+a@4UD(3F-~%YuwPTP%~QSS#!K8KxSn)=p%R=+-1n zBCEYxZatyRu8&7AcrqZ7S)$=SlVuKt)}+gw8lv%T2*^t)%?%3D%Z1*kl7J;}2Fa7! zK`<0h#EG*u#3rH-YQMfA(;eOE_Agh3@SAr#3yLVh=k||A6cRQ^`I`Ipw z2S2Bq@t@awaRb_2X~&)|Lv^p|s9EOJp1Q{xuWAcF_{eAfR)eG(NBDPaW9)OA`4pJj z=q*ZLBj1<>My{0A?aeEAbLG|{z$aG}25ZE&KeAR8ply2<3syYEMWuvVkO*^fB@_|P zXeTvR(EcFj74>MFFI+Peytwe>Zr0u?MRJsXB{Q~?bZ^V#!3 z+hGI?y1rY3`c=G|Ik3R9v7*NN#3=a_qEacR)tknw9kiID+O?u4r|~WFzB=utUL8VI znZJ2Zf2E5#%)`Ve*H@i_Q5|5WwoM@mjs1SlOCqcXT$9!|4Rt?Gd!P>t-98~za>c_O z3-ox%+b{9$noV+{nt+#M|hXwwvXNykgKd%<3Tf?^$XJo|C^KU7!>YuM1A09S3ran?;9z}-1y^O z8(k1E|6S@?MvxJmIpJ64oNIu;y3Vsn!%9L5i(gyt)Q7<6U2)U|K~ObCOoJQEPyCb^ zRd&Yr)84xCI2+uzXe-#~4|({IcIUj8wD$z zD~!SX*?wK|0A$EXD#BMFqr~aPUUQ8*=iEjQCQ0k7R`5Afe&eWEERv$%`}(~A_Asu? z(h&M|r*zx)*=^!CxuE7-MxvLPvLza2*jCVk`-VxEu> zTBYQzK2+<`s7UGqXs0nAr&|KD@^N#>P8;wkRLFh=#DuE%zL;Lvl_K;XH%Y<+8y&H* zmO;B%7jVfu(ciaw)ltlTm&WJ@`2dv-KkaIjKN?Uz$`%*3!(H)O6& z3yXlfMdjG)!+>iDy$iwB?l+v0Lqhe@jW>pEjyI+zOWyEmuSUDIWf-Y57JwCbqGrad z`xSd#wF5#mR_Uo1;F7E8ei`Gze>(?x*h@Ozw4EA(xt(f4s$V|=Oq0 z&40oJCs4a`)*2}+t^#qjmAZ*;3j~A1VF16UpHoJM-#<>B5v+2`hMx*APOVZ%SwSB| z&w0E{@{g=}Oo>6tOh+PD^f+5LN^9;JI=I$@=A@f-;sv)N$GkykewqRSs*h!WK7eOd zHqtnFW8F~%W~oQf8HE;HA%Mi%pGOgeD2CeG6<0N+wU&`Cn6{xdl1$&9DiueBI{74WN2j!$2JH@n!Z_86{u3$|-$E|1;Ekh; zmI^)Kxp%}=0-lk+idYPF>mmgxq2_axaiQ%6kEw-)>)0%Ob z#249$7-w<;b#E3NLBV!Jkcb?x1d_9~Wm6)4hjg5yF)&G)=2GID&S;I@JT3U=7g}Id zaa~=*wwamGVX%Ow7+mYIeDsHgsy8M!a`s5&%s+F_*TepeVdrI$lg1HB$8Q#KpfXlt z$6*YIfc0k%&Kr}a*k-YRjnA|KK1WTos?%xgAvZDBO@}%QWmN$y9uj&k)p17_)#7w{ zroO&h8BJNqTRf1VFKF#aMEa^`riBeh>dg_PUj)F_r0m9&4mTeuvhoYGj9lM^W^{vO zqehF0Hs>T;cf9WZI9@AbJa($N!$N_m;;Txlul-3aX-iZ4uGx({tX zu+**7werhdWD2JcCE13`H2`G9epG&t5G|TJkd}Z zN^uRpL&)!1v_DVOYO7*l_hGr_u<~UFyCOa+Q9uh_4_yoP?)|+Z_|e}>EJJoH@$dCM zsj!%bAsiWYSDh?8HPYA-`%(hcdog|0ZU%UtKIB1%7aVzmKoixqj_7ZWU)z!)-<0Mp znr>;T9WFnmKhx+;k5wR3ziqs}R9}&LGee>TCwX%xqDb?K>s74zCX=vCwLP* z83oIW*rvooJQyz+(Y$JsV`D!G{SE`#I?rr}mpfjK#})@%ZaYcwNPHeh6NXDXjwDec z(9@l2{_QO7*HC}%dEKkNoplK}yeYSbG$6rc0gCqBVwcngJUwV21`ezf zUAc9eaPNoUzTcYFp4LG0ARO6fZoP-pYO0WNN$C~&L`~D~A)i7Y>#Ww>{Zhb!jc50; zf>8GIpknW9lUq-Tm+Lk_EnVYG#16v8MA_evRU$yE zWpK304)Wqd?R&)1HCe915y!oGWvP2BifrRYU|uZ0;AMN`SN0!kQ#e|futIaJh#C5h zA0;R9xr-U8E)F1Yr{yAN%y;o8nQBdT_et<%rNH=|Wl(Kk(JDn`%Pa-~TH8Z6rDtcS zM*+^T4dNVYZjdNSc;+gToPPVl0U{7!mxbnos=p&dVKk9UVJ z=!d-)3l}MrB|E?pP1OX0l`mw6w7<~|UC5Ydw?|-zT??fX=h_G<(@6T_MgpSt4lPVV zS9Rq&`UJ7v!|+5R#&uEi|Ix%SpQkID3cb~~LFa8x?Xr^06aLcB+I>er82!~URlf~YibAFO;1UE=xR-TeqY9_$s zwf>|{{wsCvk|I4}v~#I#bl)y8KB9;t2lbLYx&an9q~7*Dv9RNkYDqZk?S2Jc%w@BA z5TovBocUIs*|^~LcqsVaYL-Hj3nPa@y?-GJLm*0$#}S9x8aEZ z@OW}%I^3DLc4L)U_;;us*CLcExM-MVVyv>}oqcj#W_-EkQX;6>GI>7%b}B%Uk@lDS z0c^{j>;h&|fbrn&USYN9_R8soAkUAo#{gf~I=*|-W^-l|KZ8mg+k`MWj7iU+Pnsx% zf$G22kO9dd@mq;9oDZzq+qXb6qZ~qRKjfDPIFBrr;ODfCnj!+lm>5Q2!aA>X%Y;mo z;LPqMfR?KndkjZjQ4irkC9lcb+^Zyf!aneFGDoA+lr?2y2VY%J(8xJj^wfdQ=LVMA zMOTd2Bm1rias>-)jMr|^vdE{@B52Vqsy%N_v+&T6TGO?2iNClyHS1SO3an zxHF*fQnrD*Vecb`Ct!@Ah&QN+1;mf$fH@b=r^ZYUxww**mjEBHp^6LitCa$4dPMrz zqU*{=nl2&%L#!h}V7| zh2n6|bkW_q$IaO!aJ;71QWCwo_ZUE98p3-ho=)^qR78RzUciI2+p6>70Fge05c$+d zzc?dXLStt*u+4lrvjnXpoz2$;_(lzc6TkMO6y&ResE;;$U$T8zq;yYbGYXGv=^W&0 zacDtj_K`Qi zMfugFo^keEQ_*Ts3=@tNE@4zTPY{p3!xLZaRfWxM#0j!vDnP zw#w`ha`%|{oDJxd-B5E|xiIX_%eCHu}_1h`}qQ3gD?xo&J$jLQhA>b*Mrg z!_74IWj_l6(m|<`r{_|0K?haZ$Z48+t(4P^Fx{!2C@#@BYEn0S$rsWZ#EW6tEXD+F zYWCe5IkPjYh?ea%BpdvESWB45<_q4eA4SuRO3_!Wk3;@hdnN(~8x;6Eoac&YWsX!Q zqF3=|beV?TcJv@10T=f+Fe;7}17pq^*J6*4+%6+zqu&W(%9Si09Zk~!VLk%};A_G9 zcuVXvbQ998HC;VJM@g;`vQ&C6EJs_f%e~P;#)N|id_HRyc6G7bwcm-3iY7aEB~5Eb zyO2L1u9JsbO-MRC(sOAKMBSGq8c8B!!iLu6SSk8{ZeOQeJDw>r*1_W;rn@7J{XA~o zxrHRMII#;^654*^>ahnyx0#cBY5ZoG8Pj((V0%zj>N84?Toe%|-c@jN4;Q4n$ZpUE z!i2=Dl6BZvIN<)`1<#BsL2#?YKusCBrbOA&HMaH_IHr@DhQ{F*ih#T(hI2 zRlFhN(&;auFhVaN(AJoGg<|ZeI+_LWJCX#6m`tF>H6T!hck1wS)9H;@8xGLA58)ci z0m)@bS>U76GLMPr+Te21SqY)}*-`ITA3!cBdjkW=ITkEic2Z)-z7fMp+8V{JpjBkHBSf5R z9o$_@zeS~ys^;M8Hh|ofCVP#=M-L%Mx71)!6z+92BjeESjW^^L*NVo}Y<`wJvjpoF zpgy83k0JL1iJ%HYrFuXjsF`vX4aG>oq^5$f#}C-&riM~E4i4px1z5^){u1;O_VLG2a@nsMPlG)iM%8$?YQx|sym7+nER2r*YY2*N$5m1 z$4SMLxG7+-EKkAv3ELO0omB;aRgvmLZIv^U9uikFZOeP9b1CW#aHUWB*k1;<7>>;D z#dAR$ICVUlrQeZ?5G9S$O;okp(i^WjMWfQGVUqSazwbzqwr=zfyT4ii=@n9S?*4>N zco<4&8zY;Ba9?B=>`=8BGiG=gX9UYX=9rbfLL2T-{<6k!jY~#oIHCMVo_wV|pKk$G z5DF~yO>rLk#jj6~pJt_1*~rnRD}mIe2S&ox26+>Lyx^vxx0=sO6Nb2V&)>gHMtO)V zGfbk_evW2_;_)P)e)jC0H~w)A7sfh3ApjJj zJ;ev7D{?!Ku-JZKpZtKM;?zSUqz$coNm|mLP$_|#BGkY6xy`8L(7ljVm~_O&H+B_C z`tFjq#_hVsx=sJ*?~wahD^rqgHi`^)7|2sxp44O|pL!Hj$Gpe1nt#m;Mm3Z4R0(o; z5~p4pt@(w5^3FMajOPecAzBh2zc=RHr41@-his8`{Jvqs(FeiAmO#F18g_*ioGgM= zTxFz$cX%~fCYfsiJROs&9Um8j5pzXFA+&RxNkK6QXGI_mTkynR;Klu#7c8;#sC|A} ztq?b%i+yBmSNW)JrM2*azQB7Zk&wl7Cj_7N{8r*4ljgg?F)~B@UkoMcPGMu$Z6&ta z#)`VB_X}E5AY1`z{DCRLSjt@iGV^_y6;+D_rB4Tic6W)Ul5VIQ_$Ph;IZGnDdemzk zl-?Odz&L`75!RJykoFO?JGUHVl)J6NV9dL7W(Yd1QDuavIi7WY0zjpHl{1E2664&Q zLAFba7nVqrHF=T9?&vr&o7Xjpqb(@otKP5WyBoIING{M)X8}Y-vFw zi+34785T9x35Gdn-sohhu4m$!!#3jn6IXQNoFqbbQ;s?5?%(4-%mN&RAemSW&RrL6 zXZ>2)hcQ5CbLu9r%k#W#e_#BmNBi1kI#AB0k$oecFVXVdM?jZj$$uP$4+9M|8c5vx z_L#wR-0FGX=8@E7Y%L`>Olwgd`tDG;U}>Q*GApi-8@F?5J`N9()ZoRX8ddh@T#04^ z=yJP$`fCkzZ@PoD+*fSy6rZ|MJQ%JT!E3Vtv8gc;$odv)cKD=MYiS#~#P7RepNtur zgU!&Ug>IOuwj!}u=q8pEyCn*#e~3d% zxo2de$dltqeW=zJWWIGux`U4!h+@JySYxNDZ)~J>T_@Cu!!ijW)cBLeD(T~_?$>8o zHNOfrvzOObcCs_d|*oAa1{zJx@sUzVPN z>glq0C=W%B>rM9|3PLGhX-;|-rqnP$TKz_q^0}T6T(a3jNLp4iS9Pg76B+pkb=iE_ z-K@L`eTI%8_Kgcb;&9`{6BQK5h-u<{rBiSPaG+B za*qZ#(uF0sur-!C69=Dh^b=1NMxq_}4~%SkmAS|g(zdDa9~w@&bR2P^_`h-`6EIZ# zmqY}ZcW5N2Iv!I1LqNR0uE7AQahAmO25!Y|&iIk?3hjjqD%kW(F(yOesi;a5$)1kL zZ>RVJH}{VD8Xuv)l1V@@t%~>f5vgNxz_$Xed0WikoSf$;7N4g@sr5TVdgIBZCMog3 z77pL~%r+xN^Of(L49K@hKoz4J^sb$OAP?R?*F`#2T1M2U!^6EQWCs=wA=H!irAOrJ zJ)SdOR;A`gT9-kLg>Z%wFb%og?^hN0_q2mk+=4eoz%PwoIiNT))BkK7V3`70s-=LK zsrw*toiX{Y{~xP~)mF`QE9#A( z>Tn2nUg5R3sOq}t_CNAmtoLN|u_yVk`=?4(2$~4$)RlXT<+I)F0E7GSH z!62s4=7ZA@xavT=j7bMz%)Ss_+}8S9L4(Efg$j}ABoB(h9(<7hq||Euwyn?J2#>O*f8g?Av3mRPCTI(?An1Bt1tFR`ZgfOP#}I~%JxTxEgfMATL_2^Sla!$oVL#o z>!vchkm4Ljg;OLtD;mG{LJ%0P0xOJh?(QIFo7*4_YFnVLg<+E~t^VuU^+7I8GX$mZ zU#gxQd-)T<5>L+&Jc9OMcO(?55k@93BQ%`c$DdB_$JN>g_^J?BV7B?q`^X@cu(v;@ z-M~G9vn0MNrC1}<6P&pSTh?cMu(mEype&2U6-rNxkaWhM*mo)x2Vi^dB3a4RU8Y~8 zA#Sie<5_gG)Ul0lUde!-GZ z)(uejqL-3V_MF_}h6o8Cr)r(n&UbjfmYZvw!B>Bq)c!Ju!WDJpw(kO2B!?FuiLp48+ep#;7g}q-D3FE@YwJ12*7oL@~`t% zwkxyu`2T{Ng%bYX4!O4EhGPVyJ#B;VD*QbZoJtRwYOW>BX%hS}F{D$y0U2P|VFriy9B3Pd-N%iU67MDlb6rARwaSA@PNsvKo%I;aR$eLQ%&2cgiKR1oyjy{5 zivECP4v8D>mIxHM(){$fjgsF9IJn~@Qi36|btOVzAIih(WaM`+<<7ZNZ`nuzp^l)9 z674{?l@*A@bS*P3t`!IFq~rj_w0$El4t5st5@OZU9TWzx&IFE3pZDvCT?d2^kt zQGA%)zBX*Weocm3R2-7uc!nho?XCP_JkAYj=?`~59ryixwpS-z+-Z%4z4Ue?w(ukH zo~)Bl6b+k#PD3Lg#z2yeDVUG*PcMUM*6>=5#RuOlbtd<*05fLHR&M8vN;n7gzR^tw4~3h zc0GsrhQ{T|-b!r+MoBn#loaB&1D4;f#{GO!oZ?1GCDDH7-zEzbYGAE{e9;^|;CZa* z*JJ`B^AvP5Eaz_Zt5H4+1f&TMp*)019 z^3r&TTsGJHfz?wfFhA1-dx@K%2A~yU{E9kY$drj#OJr%gl3_y71~xJ zeo%`me08&+S0Ffk>rMErCbtrUAqrgOY^oX8eK~m~4mMkRbmgU>)?d%Y;kW5dYUD=> z(;ocux(M%+#gZ|K?&*mfW3S>6t~@40qa{VS%OHXe8JEUo{DiRf>|G?Kh3vaYjXaBi z@_WyMK^3*c3*$lLa_v9yyfuhf4Y@3_p!Cb=esmWRCCi>Er#E1n7ToY5I83xOk4Tc> zp=TsiaE>55>cq2JYmJ`o5ni%0>tB$STD~{AW3<(jd->D)hUJC8X~GayZdnCnC#bfD z3uw`2VY3g--|{naI`IUWcY)ZgTVJ4hBkhOIhV>2)+eJM~9=xuUrlo{Z;-rW&R`m%S zl_VUIgN?;iKM{eIEU7f$eUvDt%oWEfMkFuY{Yr4cph7-@UP%HyXNq6)b_S7SZRAP! zYQ&+3ZLW&ZYBIJkx-J>@6f3Eb(6DHCsX{M#?_7xw9V;}>0?_r|1J+9yYzpe1RYtQY z6B(cE!D8^*LO3w#F<=N&`3ZgQcbnFsQ?})eDb-$pEP)Vxa~1MyC8to9bWW_j1os6t zv+Zu`x~{bOf{s$z_Tk$Xr%v!H?XYc8Y(X z75^YMO9a#&bkWantvBK3Y2WO-ZdXhs55+(o%4AK!&|m@B4`dIPrB(|`qw@x#x^R8S zD$a90E-t?4PHz~fU4;3`)bMBvD2uFWkfiSr__%er3@dgPJ!1JEz7*n~@ z;Uwe1h6w44IBVc?sk>7$UA&f-@gAgaI0QPs{z~RS!Q}fnB)*@EAP_GR>z^W==;Mk7|jK1$Tgy-|2)&B#? z4ejkR+u7Q$wOs$4pV}VKWkvgrbg+McyC0nXFTZ=bA~ovHFo_mmQ8)NI{=d*dM80$A zbTzF4=HM+^GXTv9gxH+>#Wi`k=YM0D{#zo6L5xf35HQ4ZihurB@6S9Vh3lpSrelG5 z5dpU-n7i~W52J|iy#<-V@9R^aLcS*4aV(Q`d;bY3#}FfT11KDlFPXV4iHLm*agFsN zN-n4<#xo&(;29_juoHxqk6*K7{T0fI-xe>5b5ICQe88GzPbHuT1CYrxT?yYB8`N?V zd!Y{0t$TL&7sU^?sF7r=9`sm8OYEqBW21$Cr?XUb<{1NJuF9-Z%}g8rV_#WY2^Np1 zCYONoXUmV3#m8c8$2cm4X8-m|43Z%~$Lw7m%Cn8LJ?s@9iG_#KX2+>Nac-*r@Re@~?OP;(d%B=j$4-WtO~cr8ZMKYBuzdQu+%C zo=fE5SsEOb+l-+1(v)Qx7#SV&-58O^=YRrf8L)&0h<0X~wwfhQQPmkGrdR}_u zsG$%-i4YCcg@N?vbjJk5heuECTs8V@Qq=3>hg!Wjf71Q8u&AH**4AWd4ZBmpBIVfB z2}{7-%2`51iemHbybZRy?G>6Iqkb#xH^cA&|20Y0Q;Kn+P8wH#2Vto{QOaydb-y+B z=pTzw`FSmM>|v^JH2W0h@}M7B1SVyt{tggwgjmD)XlEo1a^w%Qf@fHxwR$2k81dg4 z)~h!^%OY^RFrm|Bu`Tv$t%*iPnQ(`#rD%hDMzVVSV;e%4Z?R`RDb?k><+rHYiL?G{dhcl0WLM8JjFQ?OKhUrW4-sM{NyXH9sKu%P*XmU; z?emvl6EUp!1VECg9h=m9D2`)o05?3{w|ZF@$8{L~nx*SZ?M_jnY^oa%;>&hVW3!tq z;yfF9jKw}{@sk}clWu&nPV`JJ7sUP(QD7I5rmpVnNa?Z#uuq7Tw5f*Fya62e>pKEa zw62>Hd&zS{!ew0y_;TUAF<;45>{4U2J}qc&WBd^G58Ro;XM!qBy%n-`zVv%oL!Y(JPkwgi|m%ms@fR*Z%ZH z5;I}JPL;|Ix>#cOEg~jplJgN5WqrcSCP0Lwdn2}-t^3vIE^T79d&m5lA5roOA2Iw> zA6Z7q&)K&eF%Tp6(;yidz-W_TX_ROfb{R?AzFYFj##x>wz$;5(QS?hC^zVzXGW{g( zb9VL?>5FNsUIKGON~SXdUT-OY)F*_U-?mCL(wo+_zs6)7W z{|sU$2Cqu8Nleszft;URJVBVN`*#9&+aU|X-uxOs;?#GeTcbiIcus14yEA+kl-(dgq!xB0 z6Kf5|XQQ(yjZIuBC#mRO{4<&Ilv3%xemkAIyaj^_H&fyF&Hr89X>!99vE_l!5L;b< zSY6*at7`aW<4eh=)Rp2zjB>wb&b{<)qn@jD<_f1;pbW^c+T-Zm0~ByPt87TQde0Htu0*5gkt_d-NjaE*QcR3;Oq<|vxLT#w zT-cI;t>-s-c!N2ucpPukeJwjl&0#{dRXWChpWvCnPCm&1Mw=9SzidlkYDe+<6MUv< z5#Vd%zE1rr*$}*+Oz$iDM?`v%v%-$?u?D(^*>K0srKc@V>T&=_%dbn7=j?96ni{ww zLdTSR%7$41_d7gTL0VS%7>>8kDJ*OEVHS=103!f75kKw*yi{*;4a14#R3=@6T`tQl zc|X8#5aji1%7U+&Mx$U&-Cx~mA@%wjojD%~gLH>gPd|+BeZMHsCq4&t$FVKJh*Y1B zLKo*xNYSV7^`ujDHZNlm=wd3$dB~LaLlYfd1svy0YYV63Zik%IM}G( zc~sJ+w(XKea9PX;sZXLLZ^2M06E@fHzr#Yo253|0=I~_J5s>op!Y)$6;`Akl+Z281 zu>}oe1e-kgnl-v$S^gIpA505jj=&M($+Ag~N5!ytl7R1K8$|7|i)if|2b4 zaz;c?&Pi(7@bbYmyd`9#4r_Mm9{7-e+MBv;))jj5BqCl6yrOkl@umWYn zvx!X$+P6Rj0(aoRSg#@CIOO1%3(3_Tuva`rgbTBWjiXAx!aST(YIVaT{pw#H_@cTm zf#?MTnopv$-Vh@^DPlObO?~V4!-j(k@+Yz(pxQ}6Wg)hZCIfZ+Pq9S zX9;&gsDSN+ehb$}5CAEW#&?^cnOEzoBC*#Pq|<~K`6!3!iEDuFOp5{=0?n}Te28raRfVvd>0aB- z?hHM_uO}l$ok=yuA61GaR24>Kd<+-5%mor}LK_u|Btsl&(lxVxI^utvkJN_g52Hle=+eP_{&;8GVaH%0ID3je$1t33ANH2;~stKaW9%}ZzQce zvEy9AuY_auVXJ5q-K;lvJ@Aw(IsFWqpS{}*!@TtMuxSB5j$PC5ZJ!w4T8d8}o4 zvY_^{Hk1d|sH<=;er<1lByMv~XF9r{Sx%rRQ=Dmv2Hg`*IM#GEj+26czB3YrlTXmJ(?qpesd)>U+OZ>W@ z#9=zi={?z}cc(GU5sUeYH9@e5^c}%+(6jE)PDCA#y46Qf zbv4g1smW`mud8q>B2ZzAVO|#J5s5WbAb)h{HMWr@x`*^W6r1m4Z0^dksg8L6clK-N zh4FaRdj}nBv4sW31N6)wVY(+rzZQ$SSb~lpq+V&#ZjEFNbllQM`8@D zsvOHgo?qIf1@T{7=;Qbih^Cc*pZ%^%u<|dBQk|h3I7Zgc$pzq_MBlBX;Vbs)rhX;j?mI^cw&``=@l3t+3cN6fnuy=h{u^B33XHu7V zWYF!bzC;}4?IZv2C!i9{1zx@9dn7YIL@+{354ej>b6<;kY5Kb2lVF{3m?2(Wjp-1i zDgA42hQ_zoRSm73jH<~gH#Vd%ECn1*3_h7|qKS(zAD2fo9seO>24$(Y#FNU?HXVTP z4^kB1POJ}4U~PRWlS-hAz7LAW!1MgE5L z!$%b#vo)u|7-A2%s<$N~N6^F*#czw!qr33PJJ4$=r<QB+PPLRix#FXcHziUl=5N>@RZHgGn2X~(Yd|Ug}GWA{{wcaoE~;v8EPtVB_KzU zfoqI=Vb!3+1B`R7jCU}2LMwcr`5gMoP>JRg%LbRi&NLboXtXrhpqZ(dSs^=<$Z?YB$KtaV!6Dml5`|Y5+sTY&-}bEYx4bs5ZjXpAE=WDu=v?; zhY!LrCa@vZ#?V*X$a*FOPWtcu_BSN?`>NSi z*GmKR_)PVH##|(-jQRICR3@8SIFD0m#1e(cvs}4)*}h$g%`=*~eWq*hMSYJh{b7Cv zX^UOi*X#lX%&64~)V@0p$QoSl*VfI@PsJcZM){$KuPt4C0d7BcC&z7*Ypyzg+-^fF z-Z@*ZG57`ye`Q!YTexHtyW7^J+deAej>prVu_NWkLsNi!0&KCAn@DL^y{Tqp&BEW zV`%b6Aj{*xPt}SUdOnAyze74NTHs^>f`YsK4m@FIHWzQo9R$dEXt0%uj9MIzkC`p- zwS^^spwMT#Q25UbQ1Yn+BG=MsHC4_wE-_tyAo8B$2m*so5_{2G@Lpo&`9cj9_pT%j zDO=wC7(8*HU5j!~O&DEIBNmo;zk6%VD6| zG5DJ*6~#TnlVguf&)ZZ5)Xl!2$8ti4nilI;+=;dRNafAQ6W=yEN=(983Y%3f4UkD- z_{6b#Y=pT9NSh6E)>cE4k1TH1aOeXj8Tycw>A&_rmn{Cj+!h0F$vT_Ydo2dwPH491 zB+>+V6wH-z0)Ru1?4mz_Er%j#f2!iW_62b*{2mcy!E|0ajk|i0ezL!r>)_zlu9aO5 zD@$z%GM~2y^xlLK#{>d~?;w6ZKA-raR|Dry|9K31HHK8@0A4lBXJbkf5|M-pl#_ol z1Ok>?dht5d-x0b=E3y4K$Q&0{4(0{B@+f%PZw(R8r9*8>s>jCZ{oV%na6SWwIVDFE zy{O-LF+`K(aLsZlgkscYhaQt&M-EwXE)=t$S5NZM|5~FnF@NWN(Z3losl$2*1sAMs z7QIRO(5aWM93dO><#0a!QPG?HsR<8*1Y-4xZ^t71PHF)^TfuyoDv`!_R+f`6^A2d? ze*@*&-+8U>Zc9WdAM%R%(s}D6z7&%@VNh+M?rN`s z+}R21yDL?$t23k8-kZE}9xU?C)<>pGaGd)MyHiz)ky82T+7%!4$rcS)Lt1xAA_WOi>fd=@wR}R!R-8 zktPmU0%`e^SX|?&Bpem}sPACPMl-!P?PGdncBnbxz%f;qq zau|gEcY7Z0lQyn0YTIOA?Ij5^Hv=VcN|`QV=)0XvU81|>XQKQ*+yrHT0s#q#eQ@8e zL&1tcdk7vdwkf~XD{d|+c}@EmUMJI0SP^12qCu^Liz?6@#w37^<)$H1cuK?R!REuL z-@~aF9#p0#`#Nd!^r6pwk4-1&8*<(M1~?-0lO=)R zx%;twy^!Vq3BPP!`tGUK>B*M&oZjd;OvqUh&1Ww~509O6m+HedQ2F9^mP)@-hY?qV zd*O?=e_)|!OCD_PNmYmKQya4;4jZ7bzhga!Pb1u;*B|n{Ma_Daa8WTD_c!gX)x3%)x}gW}hAc(1PIWfr%EAL~ zvHh^%gzW^f)3#&=FxoB#i+P2z-|BHQAGcYiE*`a{Q(HrhT4ytZzJ*=v=DTE?)_yA# z6lkkJQCW}!`~eiO!U%-c&V11NJcXDB4O?O~{80q4j6A4+G9&kSXCGM7D0n2!c1%e1 z#8h=i^-Un@M6>B~1>loVzYxQAW3M48qi_#~jrx3$h$sQqoDcq}U2K++2%PymKlG&P z4xo;o%XmQ2Z8u#B*@lAoW%WNegdY03Kx&{n>xuww+T*!aPIvAjVm4p##bR3X!)dY| z^F!Dq!^1!$7cH0fpWY005A4Uz>tihbAbR}7|2UulJa2!>$Pf$c!AB5KTW$L?jxXk$ctLMvmbLpSKyza$mp%0MV zk{nq=dl_6+G*I}jek2D;t41U|^Elf+$@B(x}_$VHY$l)dP5D!NnHCW?lk zGT;vwJxOO*ew(KNYfTx4sqZ`SxQJSs_WH{eG#FB#&Pd(pT8}o|%iUmaAP|w+rVfx% zoXm-}Zk{F@9lMi5h8c>5JDf#d8TWx9-4duIme0>uik)=3-!oHPjK z{N#|k#l-(K1Sdh!0)w=nr&4=Z@J}x`ff%i!Pemh3Kkbk(>qek)Mg$d4v&g$!>dVMm z8fwEklA_?MSw^xfHkX3Xo~{o|O%4Z(p*9!K0zgt1Hhx#3`rwJ5Wm57JaeBYhb!uj_ zI)Q!Bd0`2EQB$5S^RZNtM~UvCd)RHF6{=AveR{31=wcqXUY7mOVR(lYmxQ2ZehaiP zWf^B+dxzWUczfEyiHqWcRJN_G)*tb{ zf7{-Of6jv*1y_+%ZCuhs@m^cN=TtT$-l#p)n+WWC2g7~mFDo2O~ZP}lO`Q|vT-%&|^0KPSVa&lVT+X_)wDKYGN3!^EM^Su6! z4}&v^qhK!j236ljIR1i@gu#mqRi&iTqHNQCT@80BJvTMgNA$IRA7AoQ7tKHKu3L*0prfm-9z2^viR(*clhbyy0vp_tA`kNWd14953 zD9u;L14=;@P@f@AKl6ivI;KrqyHecoO}yf00aocmlnhLLeIA^igPjSY+w812ZGAI# zFouhNO(OO$Cyux;%iihx4NmF)bY$|z+7RBLC$$D=>vJYOb!QAdjSf~xRo9*}$$Iec zT2*NL8$Yv2UOn9i6vn4Gf5(IP>(z86o(WgIOW|FYTDBjof>vxNbscLX%b9W-CETYC zx2Pr*rnpmh$-2@5_+b27+cyG3$zOZSgoFLuEz386I1g3S`z8_A2$vuTfVVo zdbX0G?3t$MC+mLLt5>l5?@wKx7n`x2pm1z41)6xBmFzaqSXp4MRAyA>cF!isk9c1F zS8%E-3J1r^mGMz4{^~b=UB1ocCE;tf=|7hw)<-ibCEn}(0pu>Vd9Du6YQ3gw%OWgm zSFqbcaKVG05P5oj=!XoE5^{iX1dR#Bue!;aXF^e{8Ii%)2bReOq}Ilb zQp^d0lqE~?gr%RKov=^bpP&uq^Mnv;%e|r$?;Wb_8ufg`JfQrL-%(YvRofpU+?yx$ z$BI6lv#`C-{!`pR!Qs~Q5H;r)Y08Uvp0d>!U{Vd_`c1Ec6=&Y9fYqvPoUmD5Pvj?~ zaqvW_nx7dQMXrv%+rKT6pufbQp7R?BU5FSqX3k9M8#mh@UtNgL2h(c7rFmyT65ocP z69xyANcNZ;^R*2$4`1$qsC(T50`@fuN~AG5@@Ldfv&z40uDc}sYWR$@Iu{F;{{*Ny zl%^lVko`f&kTA&s9;~OWYcFrNdZr_sDxsQU&Z;@U{)~-+D{yK?(GcTx0tI-A+@GhY_tWNlM7G6=`>F)FMjPTnO&f?o`y>= z`6(oOIfjcKnE=;szK<6(#J6n~uBVaj53Zs7{h-Gm6;`(HtBi^upJ1?O0)Ri7mbCI! z>w?j9wORC3f)3q_Iu-(<;#m38>uUMN7%ROI(z)04nOqI@2+R_ctki3{1FQm&}gUU|yc>SvK?L5~)Qjt;PO=!c=O|9}Mc(x0-MiKeHw%s1n2%In5IG#~Oy z`|QDW8)j`<<%-#A&ozTtdKYFVL#2x7@^=vcF>l|;)itp3c^v{)=fU)V=TwN<3E3f8 zDdWV|BQwIcN3|f^E)<0(_qmJ7C0vkd{h*`u!3-8-3G76d-b2i!n+uZRz zpb?+;7RRU=3QASNi;gS8566uWD7z8zS`q~l?d*mKy!C@(C8VJloU__wFZ8zKo(Ghs zyRz!w0z7LJ`hyP5kF9N3VD9 zU-nEAcye>@f~|J`6tK#+Dez?B!aSh@77OcEq12!AYAoM{?0vl3+Ig+X;v=G0{xgyA z6;CUncF2s0gmb?468bI>WVmcM|1M3k$1l8)v8)C%R=xF@gXaxiw9uKbbz1h+j9~O) z<;$=xF+RXzLWg5SxD8~Ko2IImg8S%;S?87rx<%@s2br6qqk;nZdCv-S+LikemAFQ1 zZs-a!A0JmA;)`(nDK_)jQt~oP?*MF)YPzZET_;tnqG9W;nSGKIk*dk9j_9Iq z_fUmF9{((i!i7>OK+5FkG1!azAU6FcOlz?v6R19sx_-w*Y81NtFb zo1-+;zeIAtEMWky`7OK5RoGXih?6)gRg}1s2Ts{;=5;a&FIggnj-pdk5*2+VvM|ieQm7gRb7S-XW|$=LpIGfH#vn&X8seVs4?__0HtS2nEGid6Fqq zHpy8_IWGzTF*)_7T)}b+neVu!`8h_UDcdV^3zUKbtb&@Ffa4vw39;IGFEW9~MWRr5 zfEr=Zpq0Pbka$=M5my6a=bhsppqfANB#~4M?F;O0Bv(`8#9cE1Flmw@~{b{dH%Gjl<9nRDC-NA4YTRTb-AMJ@ zZa;)kNv)ad26VTQ17N!LnwWrzO-!a&h>wXj(q4m+Z9Y52F7BeTdx6i>Tm@>PfK{zZz+hkgoq0fz!a9c539OvG0sw>5ma0Bh0 zU!t^k(JptAG-7oKDcdZ=9}#H~VM9{u&>JMPNr)7^wJC`~CPZkW#Y;+No-o)Z08Iqm z(i5yVubDLr5@XH*B(!5sx-51DM54OcHii8QMl(8$t$>5YbO)%t=~x|ayanoEWbRb|BJbbWC@r0A5r;SnM82$4oI0ax^tNa_LJ2WJT&OPQzr{t|~-K;~=m z68B|nv&H=hZ;pY9oXo?1%NJ-}AdHS@s57&N$|yyHDIdh`RT|vy1f9GJVrTdefp3MA zP6DPiF^?#(WWhcFKGcg2-De$sC zs~q@r)4%~)_0P%z&|WT~hjMLm9~Zg2+e*Gv8ThKcHO=chhLfZV-Iws>zsUDwMU6&4A>ix!2^TLO$JGy@ zHF0xlC;_l?kXkH25E$wo={zsQ^uFic^-g<(JQA{8YaBZuO-f{?I8zHG`J{pwt1|`~ zfPPUkWAM7REUZ3--iYP9@|K=9TV<)=UM0~aVm(}AKB2#b?vf=ETpijBVp z1$TryKvnpKxj0x~(8Rpb^7sF+V+qZT4M0vkj0k{~1sS(Gr0kA_2SLBd>-dzFZ z;C*v0s%?B=*Dm&len*P&-dnX)I9qrk`l42L`6XS$m|E3zoi=JWX*#VzNX}?1Re9cJ zC^P?)=*!*GE6L?p4kA^=h^_W1bjbQQYLfMf2d@R_;`T;*@O5aKOkHZu(7X<;%{rRy z9bY!b{0;a{C52%i!ohb7>tgOpB1!Ev`WmG2MEp z#jU)u6g#iVmKNNvZ72|gWi{!S)6$fO3KQxJQntVk_w81%x+(}bKgxrnBZ^{-y$o&K zD7U{vo(WbMdR3v;<9w5ZDZn{n{i{j3)!$&GKC#42T?}`1BmH2R;MhY6o8-ke2EZ6u z7B<8mawB~%(2=DBf{Stl_Of^=J?`hZ+1f@==0Fi1aU+^r@AGao1|zKb98=rhwKc2L*7gYzn-K2nn zBWnyd^|nPE)2cNXBp6jlK~pbrH=$I9U97qnS~i|Me6&4XOA8aeQ{5|xxP)}>u?-~{ zg1?hH4@xfVc5Y|z$zMQsjv^9(jupsIAh}fer}9;q@x`hhp1ygA825lFCR1enfALmh zc+Yy#=vFMERidQPTEsmGh52jfkh8AiDAk{qI>VKcv;nWz)bivethds|{>B6|BvEk< zZ{8gw@VID@b2J@uT#>XB!)9S3#aQl=9NfG?)vCIrxQI0H6@Zp<5y4GdVkL^K!L+KE z5vD2sUBmtO_Cab31H(tT|=Fx2d`B>Hk@7W(}kP2IJ)W2%DwZ204~8(jN4CujF>_^lQ*+8AR=nlK8zTc*(6(9*;q8r zMsL+4%0os>!K*XVlFKUW1c=l)OmV!d1R@`$%bd~+;saJoG1C9O)~L`=#sjQkU+?{ zr&p)|z^p0&$gZ9RT46#{R?uIo9J@|uSJK0^DM8)#1a18^zSjWxMOWRd)|&gbGpYuP z8BNXc^MONh=i3NX!TLsvOA1UhiD~Cu532VTGEu=Y=UWf; znme?*9l=Rm{)mzybsCUe#99eaoN=tTDiM9L96~%HNGp=ab^o8BnL}}eksm*w2UWif zuVy{sk4Yhf0H6`1a>l|7Ll;S)kg}N1P)$Z|>HhWSR_UliRcMo*8_R%e3(y8WGUyVz zA5T}$YL3?R0Q<7reeKtD=$_vWqodZ0(yrxnko3YT7M<2O7g3;B@Tzczh{!SV-9NJn zAL(8_5Q~H-I@*vpsHk%SO5ofjELS37L(_M$uQe2&Tv%+OVgw#0w0b*0?7NVid-v+! zdw?3xVloL^j;Mw=hiWIZ1hjK^N}A4O*IRRQ;YYdiZ49E3hJl`4Ht$Lu8b78;!4;B? z`rZQ!sQQX1-735Wib0^6|Ib$;OJ)v*a{OuD_K5FCwgIBqt52t$w)^NQ}^!V?7 z2yt|agB?j;oOm*!Dh$!Qb(nWI%~`r9b0n}hs!hv{`0imXqem?aeEckE!7`IgzqAMgqPYU8dVt?R-FRRu|B z3A_8!z43o@sZduM*DsEBo)`RhT|O>WCzOsXMR69|BITO*cLGHrn0eyM@-4M0C@J73 zqKaLlUEFSf`4WrGZ0Y~OOE`PWN$Fg6Aq zhI_wf-y{aosL%9M6D73H*X+FwVn;p)Kh%&*ez;XWQI179>9hP~zl2DJ)h1I+Lo_S+ zP?Z3D#!@JO(O~GYOJ#HM<2jKvKdv7wT6mS9+Kb8Ox>0|rA_v&1=qQY9uJ*bIp93Le zB)Gp}a*R?$s2A!*0Dd*SLNV(R<1gke2PATzVs-4yI-mhdzD#LuGVj2Hba$YXlcYDW_Ong1h{A4MaW}A2 zzBwF#)5Pn&)P3qyKukmAC0Qnt4+lc!6w3GVwf5VT({@aeTNc5(vIb8!&A&{H>sDo! zbl(Dks5!`D8Ep)%TQKX$b@yk^hBn?r^e5}Ng}VRujy3;erTZ}%*336To0fQY7&v!N zSpa^OFs<^@3kt2%L`WCZqj&1Ygix|;E<}nKh@l*5=U(-c@w|@~C^pM!ub~$Bmqp~H z+Pd!4Jy>wI3;^!*zhj^e%k@@i3laGgdB%^FLq$(|5#^;YRgGU;vP(F%kl#puq$KYz z=Q=YRrZ`Ngy;h&`h8&wA!$Z0>tdtz5Rr^-<+#zwv5Y!u^Wyds#-6O7Q^xu8h`L(_# z4j@u06C`Dlu}QVqHIk6wqDlLzt7Apd%20=UKwvVXsu8sTIB;u5n*N)3TXQQ3>q2U4 zE(*e*78KE`$8R)HUnJ?CnM^S<0j7=!7zLN&4sRKfjf&Vb4s7hfy(BoS-YYU$*siv4 zI49Kik1kGEIM&CzpNT#{F!^Ar8DLl#^wLzRyJ0<0<^B(MO&e*ZpiZVypcN{8@|mau z*PETd;=NO+Z_9@dQ~TBMt@B(}UW#_%B$T8`!2b%6OBivURXx2^5Wa}ckeD8A$2g(8 zLCFcVm55$XmSYTN{O$<(<=cWK;4F*sutH+6lI<9UPF;S9xUDViUENLGMPZ*kIZi0K z@!QOx{&Bzu&0wfco?^8rApML?;1V#+_Dq^#X$a!4cNa4dhUXoK+`e*sP^O)k*~f=u za6~j@DMQ%WB5#Cn`p=hy-iCZXmU_f4FZKrCSQ$9_7}ETG-?PwXM6-^_p(qg#K^t$J zDf^Xj$a%y#+$REJchn3SUv|(sL|JRyTo@dA??Vi|S`({xDeo~CljoZ!AJF7x`;XbU zW}8dbNI?y*A})k~Ek4ViUz2fk3UFcgkFjwF=@}~;;RoLT_tTtVhc@gHsnVW0Qs;CJ z`By^xRzfL7Qez5*S`U2^b?$VL8!~utx$-mELa4o+^Jw2vX;6@Ck=Z+_^wWE&>C>7F zPqj-U?Xa1${Aho-nXipFfl`|%RedBjW_Txs`RPpTM|boLK$1Tf%MOmRWuS9a0xYJN zs{!KcTD`J8%azqAjI! z3Ro^`m2H+OG|&Y%^Ua?2EJGItl9I)wC0DQ;n}Zpg#*)boAMR;kdoaw&U>>259cZV!MUhQ~`pKw617p zA3C)U)I>$Kt)=5J&3?{kU+4O^EadL5Jq(%^vQ^^wU8oNg_6jwx9@m z2;*%Ql`n^=OYYFI`3cBvq*J3U{(dVal#Gs{eQwm-jMF~E;NWXiQ8IkT{77_OU%mf*!bGPNQ~^ZgHc6RLqCXk`#?!ouFLQh zoVqoRj4Tc)ZE+mGrgG7s3J;*`4G7mQ9U!dgbg#uKRzv&^ddZj~+93tw+cJ_#$!0Go zD+DW3_I9-sT{7A&b`|~K+!m(X<#CX%0J2?8>zuxo>p^#hslMW7J?Z2`y;9BSVD4w( z4cd(Pd91Dk)l`rl!l}#}X~VqJI{uephbf-IVzTu2&7eO3NkF#0sGW<~*`kG&grXqF zxO*oNaWCyM&X(tB_v92!JhPnKZGpNxq?^_CWuYyty<#bj!i59J#H5#%$Uq?8_Udwn zEXQGs=*qZ~q~(kjz5;%u{|s+(J{FT!_+l?y0;=QJPZ(+w#f-hw4GJH&alYaA&hf8d z!Uc^1$r<)BE64pP3$PK)KzV6%T8F^se?qgbMa^j*^BRIk_5R`Xv;sf^b|Q;T8YDu7 zag%!tY^~N8R`gjgCBgrio&5$ewIqgcjrr4RgK4Azqd5blByt00w~NGL$-45w{Y|y6 z*$>g3%S)z$^KU5v@TZXQbd)hV5m&rK`}xU*#SqBa>P-`cuF9$dB9c)w#fy$x#;dY% zco)is3@D-$&uEdiMyk)wrc@%)rH+oAyrjIbN3_@~qT&o(P$;Q2SGtYI@7rb*^F9&$ z!8dm7Zh2s!?ZsOe+K^^d?it_*`taqYjD3NCl(<}58TlL>=@H*xT74aGe`*#>%sX$( z^U<(*3>@pS?_ebyQyVnlQmjwo?_^~%(#jg;1qtF47>7Ugcp`=qT9|fQ%CdCJ6+~%` zDAM;jakM0`XG+5-)Wi{*rT!2eS1ob!N$q;YF~W>F&Tx(=eUO29&|x(b+S+o5?Zo>U zM^<~zCSXFsPP;TPz{q&trnQtX?R6<}!KY9BRC8|da8^v#^AYcM8yYZ_f*+lNHrT@t z&eEb#ow_3KA+aI7xOS*+ju>Hj3}D5Z#sFYfh+>QEv#t8bF~Fr|I|1gLKo7u4oh_f_ zw1N=IZ;7iy(ii^9|2wWY-_7;ax@>5{US94CxK_E(xMv?m-c?U*&zgDH(u_cD5%;nt zgusvWTvv@XyN&@ey8yo;UqsMVZ*K8Ftb=+wtr8O{DXfdD>#(4W94WH}GLIq()Xk^1 z4HZ}`vJBzEzY4f`9$ACM65?Ej`YYy#f zJB}fMEfYt69A;`I^F0fPqt8xqQxpCul~ftMLBATZ(z{wymY*@?{#3T1A;Yx`*3s6t zM-^0P51JethlOeKs_5UbJywg@#3PXpX!xlPX8;+u=hPiuP;h<)L=Fl z$uH_5oQcSxvwc7BnN>)}9#KBph&7Y@-D@Rc(L>lox9I;JJ zuUhdAq!12aP&hxnF#KHPa9lq_G~o`%IeGKuv@XX;u}UDHk*cKJ48gSeg!{+U{`(i5 zgK#rdGMzEh*cw$}mZpJWq63DN2xv#tdniwm6#!E_778yI^iDVIPGALSdi#I>(wBGQ z&Y;=^l&hZ$C^*NSsN)H@b#@8s>yDoBKb?LSsTY0K<*vyzEnb0u6JFbKVDBCrk6I>S z3Y1vb)~Zcpk@@5lPZdx(Nxct%R55!6Z1diw$O13^A<2lVb|a`*oMrlAGmi*FrpoBh z28niQ_k5?HT2jThr;Eq)1tG%B!9P6Dh+m_JG4gnKTq>-_Ji7h9^(BWdv=x+(O)^cP zX`L$L{3|@Rqt<~Yu+x`!FXlWv{BQUf`eh(r*2@cVR-CR9pRX-w{ zT%c0H+eWZ2$i@n90$pNGm|{+rCVPuIPRTtm%_!bsIP+(*EiE&jLmA7Dw$?(5*&Fc=KEE%M+} z#^!_!9i?O`mpo=3Tr^Wbk$DE0|VTPpq_u1N#n5Bq5RMj%& z$xTOTCm{G9-nK@k1+O&V+d{A7%0rOsJrjo(7}+*ezz3l7g;p6{nDxsjcEUr&EN2ta zutF!81OZ{&$Jcnil0M{w4>Q&6?&V_={-j3I&v;7A{{1hJw|kCcX$<~492YBuvNCN> zg%*1JiYM0guyZ>{)!$lb2m<1qyLI%$wpY6zmJ2UQo#TT28o@`?1~?a|I5sqS>@m&- zk8}2~v`<+ZcPOQzytAQ6xF$LcpD++9SLj4@MW^(|H3*BWaRr~xw41~e{6V&mbr|QI z;A&a`^m5^q?5bUbqB;fWdNIDlRIVCEVL=`1IHlJ0TcYynOnp&l6u*FYisL~cOjF_m zYcT!)dmIc-@^1mf$@}$oYtCeY>BGov1sh0Z+*$E9`T75$(<}sb@26%n!Q};t|BoL% zeHD{IB07d2c6#aTpb!2QTfH~^B^mcElR_{k1@>lzQ~ z4%YTW=ze=>gJ?;E6c9|O!297fw2;>Mw3=_3oEMkQYsZ(O_y|E5P7$90Cy)FBv5^}1M0el6(%$2; zYqk{R%TW5KY{2~v1WbOYE6Oh2U_{ai_NdLLov_+S);u{iwJY!qVXTpVpbm!Vd_48T&pS$Gii4@)lv*`FR z67PZ@ol})s{l9xgN6d3;jyEADMbe zNdpMWHKO)ZELs;qQBDOu<&`KAiuhuX;~sZAG9te8;$+IgTf<*aPcNqYsuk>`zIK%> zG`jmr5jk3Jr#Z8*Z!POQ%^>Ar-S9oEV=yYQ2@G)uj(j8m%U`j61 zG4&VI#8!NnU!UNPdzXoNLnXy4pgN=k!#u8gELrVp?$x!(>cU-*_o}!Prpeqof_St^ z=giz8;hcvxPa9>QP;1%T(AcJbS4#9t=*FDg8*AGm`zFTeHghGI~mhwitGxF{*Owp@emRw%48S z7Y;_7iTQXUu|cd-JTw-nMUJ5g&%+VqN4opoEW=+;Rq}W!WtyN@AD>{ zD2A1bA{pTmH68L^iIb6p(o#gQ(R4QKmz2VfVE?QQLb18$ZJe92%DCsLPguwXY#2N_!Z)r zwQUp%X29ldPd9{({Lp3?rTO9kZQH8+Bsg}cK2C(aY5@5 zC4?8Tcs($VAK#}R2`lZ)L0mweP*MSKUl}g`fw91`3n^}D0`P|qT(5=6AKBz&N!+1Q z4UNDpVWU|Jid=AEWB9d%1V#4!<c#TO?0-I3 zxrX+wUpiT^X~y0nj`kt7cA&X0PWOCBhJ3upCXLH9P)mV+KrQUR4OZHNXXZL?5W`N{ zCSd&wCpuzK|5{Qp7_=3TlJ2`fqWYtdk35s+qwN^mUbspmOSc9;S?E)_L7@UH*a+=F z@AIeBP%sp>M%zdxcUqXzz+zO`(AHb4rr9j9wrwSCs;-?!q*$a)ks%9tW!8qv!FT%Y z>l@-9izI~u1K6;uxRvo~deGUO%D~j=7mcbBP$kL*(#HLm(ho zST(VO;{ki6|8n^bf{sB8re}5JM!`n#rV)8)scj3-pzu+QL291duiHX9c_@=&yD<`F zf(IHj`imusj>v9Q8Z;hQ<8 zXUc%ASMqPtvUyPGnQL`n-!Wb6utvfWJ;vcwM}8h|OJ&Wm0PEv({=q34{+|%@aHa4|#dG=d)pwF?7M#Z|qxAr?4W}F;AG$&>C)uXdwYAv8H zYabQAQ#azWCBtpyJ7#w?>F~*F~mzidt+UrW$N=5Sf~+`@@5Y;8Vl+XJGiz|J=} zpK295+Szf^8jEslXzqU+{krQ|omEjX&!$bBdL9mz8_r}uiK<@3j5tHMKM%LpGKvtI zX1PA!z|FfmPI<6l^R&Z*--S$s%UDYbTwtJ%Tq?&CqyWML=Ux^=nCMNmh*8Vi%qQ*w z)Ev*kWcd;gh+5sO3lA0-tXzq2{b^2qdGJ|ea{}{y7-j+s?RqDWtXVS|JV33Uf)f$6C61MHuLz*WriJH5o`V-YdB?KnXNFc$tL?SnQ@g{* z@tt=h>K&$30E{Uw)nb^C3z6BJVQ)sLR%8M*nw2VXd6ydxvSK6 z4qZ?XtKpK0Hl}ESN?Y!?&OuX?2r`Y8?i&nfZInHS%j*)tV`L#95D`7)_q6I)_)V7( zULG-pvo}$y=vFcoJB8BVMN=c{wtDhY`8=dW^B?tXz89<}u-m<>nWh*@qE zD$_)H0Ocs_B2WB`2`ej>086lcNUU5+Aqp0=Z*15TtqlT%t!KwuW_FDu=EdXyLSHFW zFuk9iPT8OF79ht-%vR1DViAzmL0{y}3}zHDC(bHX*BwJJso1TlYKK+wbEBDYXYUnv zxm&i8lfjxzX73w@=%~ZE&b;FByzWNW&R4E{9UazbI1bw=)hqLDrp+0E84P+PE0Esh z)2xAAd5fR$W=(Vyh5)hCnRX>6E3Q(U3JZqAjrF}JfEJyH`FkAZLu)okADdH4K$Z3( zv^=X+50#*@NSh>UDa?7om`M8k($$nvqXN4k;UQmN0Do*)6b{)A)GJB2&yTzfnNq$w= zuI$M=vj1aDQ(ON*+GBx+-7UaXe?t#vcQ?-vitF+{QxG!qccosHYY4d%Z^2MMn2Rl` zZq%TuE8mTc!I^fkqK%yxE5_bF6-AiLjEz7`W^<8@HGy)RTGu~+mlEF>qZ+c}c#t7S zp#Jls*x$zR7XUWcnv-1|c6C}%Px5aGS;0gHZRcf71C1G^8x#9e*HF_oDK5^#Pyaa; zS$ZWjB+AEh27Y3tQU>5r`` zCj-|GP_9zmpMk7lFqvx5dZremBevKPLGgDKU5Yvf@KQJ!1rS(Zk95vNMAcC+fNwFG zS9(KB%m4q;R4(PWJng+P3X#1}X2n2!fX{)L%2o7qB4CNoMbesAJr?A)X3BfFf+(o9 zsc+^XT?)PM6dx};9Lns^)Q^{)f$WJZvnv65`^G*19Y(qt0i47)we(;UQ7l=2gB8G# z6~WHtwPA!_VDVI%9?ts3K?^+E)2<~=hmBx_zxadHcRfAVCACrh`PYAY*#%iL>Q-1V zJV!2dGp^u|FPTSLq44!Pa^Y!XuJMW|$t*xhb`Q-8Mo`x5JFEHuD$?OL7Y9XzszxSL zrr;}erZ3FnQ7E@$E!KN-&Ik{(7|SX6`GI*SBp{?PN7~3enBD(;T? zuCKt?ri;e4Ll~=ZmLcd-VS@?OVxl$=hw+d*I5BTGM!9Y z73=!MFaWsaDQO5{4U(mwtWbj=<=;v3PH7&7K0P~f>L;xE^plQ!1H~dAJN?~kMx5Yl z20cn*VEycm+OQY@B&K)K%MV0?@ooL@0?fi>=+<4-!MirDIem9|EpNNmI^s~pn{pXO zDmC9X@N#RX{OAnUV#l?d^b0^BaN5bjH(79S1b(BtTq@zszrkXqDl-omJ8Cd7u_ztxdCx%qOiLkAf8FzpX%{VJJVdPd%?aJ9ysSeP}nqbkn2OY z46B1GyU0`~GGuSwP#qa>%Ct4g7#^{RXJx7)i>tXp|9w7gsw4_;U5$Pv;4@Zm>nUOt$Zj?gYyZW^S^v9%$iRMJ_1hk_@%N5IHK7-cHm16^w|Ex^ej`0bFyh&fpkr3PLE;?8^seohI0qaOm}?85Cx$a$qTj~T#!5-d z!A9N?HI}$42wO6{fWn4=MKKMLHO z&@SdD81iOj_1#Fky<_)BYiL;dsjlidRaGEG^yPFd^5s0_I_l`SZvU|EVjkW zdR+=bvMTVr@RB4zU|#^lyI?0Yf_tS1Fji5GMvLBF%C%~MMaS8IS-acCJA4&*@Di~> zT6cJfZ4j%CGa*mK+jXBt%if>F-{=BicCr1$8x#h4eQ!wvmcJxYIKW<`S?NN7pls|g zzeM+LQ;UL0!$fauc_H*9Va=hAVD`#7-oB}}xNXK4H0WU-Nv`PWyBQVemMEXw%$Gdi zV6OkM6&TQ(69O-eaJ|MEk_8ng(74cpy|CG`7%4NN;&$?K<7fJ=h%it16Vht6n~IR` zvgh)IX~k|?BJ+LBDvZuHd{BAU0XFhSw~5J+3TRF7Vk8qyz^s|+KWz)+@Lh_uRh?IK zImNP{8dar!6Xdi*q*$Igwl+LL$EH$U)nWw$m=nH;o`Axc3@GW;RFfkS<>RUfGK+bv zbiJ2F_^RCSsYaY2HM(T*Za?%{t~dw*w0NLrkeh*cM{^Bu<#r6a9%w@^ACUgrRE)PD zS05K5D4ldgYlgmTKQKz_)~`8U6e2sGJtu4pBZXzU2Jq=juJ+T@XR{yRK z`t;0KaBwgHgigU2PZbmJDC523q820wyE}mN@a!3(621aBE_i zHexeyk=2l*br7`25+W0$$829Qcl+tUJqPPDsLf-Y(;$x^r8HTQJCe{L=c#({UYa~(o5L)6x>u72#y2xoScdS z1j@%9VyaQEL^Y|!sp!ahUg6)QDQWZjC2Dfw3S3MZL~lIzY}3z>|I$Ijxbji)(d0%y zGvOq>;#Z`g{yxL}{o_E&NLhec>LlR0Oofit(kHaN5A-j9_)7)$AL`pl>|cKhnKX$f z;RRS5DV|!C$U%fXNi&w$4dW7h-pPQsR}eUy7MoUxV-0iUITXM$``Pms1R@$*c8zmI zCnIZ3!=`quGDk~2o3GJM=7~8@yjpTL*-RGFJ^>N!)XF^Sc8mktoQ3keSYfUt79J>cSY4lFlVZ$8*^u2xqvniXuY z_mARZ!!vN3{f8Q(HN_bt-ZYh%{SAwIW`QdUxi!pcxz4XrtH`i8B4(XRZ_g52#xc!G zHY=-wxOIBUDtE;D@T);yEL1Y|4{|AIVx`_I`|!AHE0cT}Ewl+&_0l2c(j`A9#aUT^ zTQ8mrQgoo)P7(BoUrZY6zxh>LrF&+3+S_+fa`O=^W_a&H2cYJDN051PoDDuFHIS?0 zg!1_F(76lTk@5u_b;bn8M1n)7RQ8?=r6garf zC{KQFTZq~9+t|?y(^!B6h`c7fk8-*WN*JuY$tDZinR|E$%=P<5VpOndxttIjH2tQX zH&cP6Wd~r~$AW#1smv-gZuKEF8+RLhSf?o|bdZVjRhtorZJMCFD5_(%)I&A869Sac zQG=bjnUt{Ris8;>{|vxS4pwaR|JlFas~BGVi^Ac@vz>{ZsfzELT2|oloMyISoQ40; z&LHOgdSNL|H6B>5#Ju9d%c@E8PKod9VW*7@`rdnF_;q;FW;uWUMJ}X@6|{O9*hRZB z4b%*7?e1Ct5T7q+KNufII#-|IQrq%{=gXM z2?^Qm-EYX7;SB(7NEu&J(yK5J?XA9gcpA1fo_HVW#1(1<1orm9vTlH5(LwwUHh#;_ z@?rL=^?*rL@I>rwRQfP@dzX?9KV>L!#lzz))ky5v6?ZDCUaP9mns0hdwLsIZw+?!r zx>(MvHw8WGh?8YT&MUb59wl5&)PrdYCuFwf+%5h=RKR6@Sjl46rd2A&z);eGQR({0 zp%KWe{+I@v1UkL9g3Nph-+G@V$w|po8 z6izpKOdS3M5j~3+#kVvN&p-gS;lGy-cbTj3Qge9BC+LEkpOL{aoMGJm)Ek(|9a3lL zhJ)qep)6%TwO4Sjo1hr-PW{eQBk6jdDY&;$UND`{$v*C(y>7* zRp)vpz$xWTPPcxQf@PcgEE_yQFsySklOHT$67c$lylp)u@bGR1gIAJ~oPQTE22!&I*TSJy~M1JS;K~ERaXlPf|5sE9ly@tfIS!9-|vU1-jMwrQ2 zNo9f)hCVw{G{WDlr>i_VO7I%!VU?Tf`J`WNES3#BY2^Lq$pAP^+rMLi?A?_ZQ1^ez zSxwXH@{EPA^MqE;rwEwE_K(Dw_C!ECsuJ5)IiQhag^Ksf-X#F)Vs>UBTv93`LTX!+ zLOefyId+&32FI#XI8VpDL^LD0cC`&hSwn3IJ_VNxm47P{D?m?-Er_ewnXYgjSoMQ;} z@8~zUy9CPe4c9mTA%l@^!(&!nWKh}v|6RT3fzwWLr1s#zl2)XwH&STM1G&WWtoIMn z2VUmVriqO466)TUI82qfL*V!t+ABKFS#`wc~R`R1!&XwpIHfrrd7Cx^6x z-Zx&fHf~Dhti^m7X^wAv^OkLE(2tm&9+QqK^TPkgfjeWcX#Y4=TH~8eErp(0Ks!`2 z+~+~Ewi^f!4!=KW8Ige}w3DooG;w2Rwm%E;qf8XpNYack1;iQ9iK4!gPvC0$X(SH~ zqVdE1pV69rhVd23qUS&duTH68B;qTEw5bHheff>%A$%a*qp>6u*9Xyd%CqoJ-+dPT0Ke7i< za}`bZi*9$^#{a7V1n73fz}3gyQ}+|hT$07?^D*GoytZ&u2QDsuLCM`;#9DeeSu<8e&y{Yr<7+OXD666$L_j} zo6>leU*4oaw{&mx)$F)=y7)9^Ux1{unVRMvTt11r+0WeOBoF5nVwlYKAg%mYQ`1y_ z86p?{qoRwxnHiEd|4JTif#on{L)d`Btco+KIC^ zYGkQ#?xQzK$NoceR8G+ZHG9&^Q)Y%e0n!4Vh$Z|sh&p_Jt)x2(Ja}^NY<as71_$8^ZK!L^{(P6P5hu4&WK4QbjD*j}H02 z49wM?U!UdcojmYaqQNTw|8?w;&$@_So@(+xa(JGX7(^r8y(0{KlOic9p{Ir?AVR_4 z-h!8-6I)F9VcM-F@%s2)OHrx%vZd@DsZ;MFTABJI>;YXvm&-@Xn=hsT{>|n?aP50S z)GbpS)VC~YbJ~Y-((m9k@B^Y=uu2y*q0igR_qokOJY}Iz0i_Jk>)yn$ZKTA8Y{vs8k_(S+8vm@-Smm> zQeQ;_xU}@WkV4653$LOZ^NP0cBT{R$-lvFA&LJ1;0<&5$YNkR@l-!)a@1?=ZHwt-& z=(AP;dVQsX1&pb^o6E7QJtKz7UR8@xE zCb1z1!Y42cShX!O38}n(gK&4-jzKOguevz|#`~Y=D$&NiD-^BI@dnt+ zFnw0kDEY+BP-9}8dxfc-f70CY)DAR8HGdfW_fl5c|4XXRxzAPZ5cY7uJ)Nv|SN{J3 z0+hS4QkUmnWCbqsUR(r0x1&T%i z6;L+?#@G2P#e7%Q$NnueO**7s@S1S39Td~HRXDqAZpKei34Q%zxn=~@;MFlDAKVU` zeAemchIy9npXB_*nEY4RiO=fOgh-MfDd-VPWbv&XTu9r=sFU4Ry1rjMP)hzjNg3%n z5NxZb3jNU(M=Kx_^cF*GP+i9=8PS0%R4@e=^$EbXgmgd5??*hlWes*wq0tRHj$Puc zzd+@;nSng3Kk3Qv?wnvxmrmsF7VBx1i9QQ=};K zKs%npS0*`QE7^0K2B)4OUhUl**x8ce2{-Pgk5v`)4VkJX~g38s9bO1i8tI?Fun%w*7V1qc#J{=+*zQ zF|b)gYa=oeihG~%*N}F$Ejo*I%&dOO&?IZ}GJL&JtHgd)JP+V{i?QS^VM?!nUsV-b zNc5h>216hlE0D~iNT(m3qgQW}KU(=^0vGNpuII@E`_kFDs>I>n_CL+H9xzo(5NMp* zDYK*#_|ocrH&h6ZMp}|aCuCD)YGXpwN32plZtdugSvTGmV=V`vv&{pOLm*2nZ{|m2 zt8WHSx7UIlrgSnp4SzsS1`aC;qF=a`5$(x)>jS3UDa=}8X7viJAU<_##h-VL@nSTb2eK*|Max7h#c33qa6kzs4|u5@ki!J1=MIkE0IyKK7k#O`IT zO061Ehf4iexf$D}!qCxc#5F{YUPx+DzRoFlh&Ix-E#LKRZFAVs zA?9x&VH>D*)4xW&_eP925Mn!f&V>7z{gI)pMPR=6m0%=>KZSUeaNd&^RbCBj3}dz0)OAbA2aFGWlGi5u}zmXl?Shu zdg3)@B9k#w@#YWN0xjxZ(rm~P?>}tBpw*ZAStKhpEp^QM#AX8RUjH*eiTEi`{@Y3K4a#JpGT9z;L?w!v>BhCL z$Eq%e4ra6BSZuB09sTi7d~rSFZ?2W42Hh64H>+@zUHE+OI2dvZOg5aGOmXjj0@qd3 z8sYszx?%kXFBl3JEmv-i-A3zdtghMw?;i9sGSq<6pi&8m&9U-7`qCi9Qdjx*qa^0c zkf(5OI&1)U1sK2Tskmeg>ONG+^Mwrm-3p0_Ih$@R8Y!3!1P+u>**$++uN~Kou9>&R zR^l_Ua}>opesU8~m&=ipzvx3W$W$n<6}5DEQG#4vH?(ZqHZamK=7VcWvsjG0qW)SV zwddD+*TDd+`U*&91uy_cAnfAuuHz05D7a~!KI@TWsJi;rN`{S#&;+~iV!x`7AYcu;kwmZ~ax&7^7F7J9)`L z)EYla6ZIxAv=tg!m-*;RS|pFLPj0lf-OuNtMzrW7QEdtV`(RLoRzv4E-=Eqt^;gID zfT7}mholx^tqd5BPE8lz$pF1%%nwl+U}cl_<>+nejw8%7u@X~XNo@;3HMxSM>@{L= z?r7c3W`Wn@?NSjEEh9BQC8+yXMPbGQ!l=FQK0OGCAft_`^<(rc-&iw%M zD$L^6Mg7Iu_~(5+ZS|3jVASuud1}>w_5<_l9S%BqSXDA9`Ilchg=J@6N(G|mUg3Tok38~zN zV^}%`1N%RUy5z6e@GST=b>(kJml9&RKUiFZix77KbSh6G>DkRlEihoS`(mkM=cG+zXN|HM!)&n293qEg_K$_yETDLN_TMLLkS zwaHy(f9a^=W1D+2{JsC`2c~9W${+s$(Awha8vn|luzm0cljExg>d5X@0MF4VX9h(Z z5GoDC_w6*EMab$)1dz}6%4475J6R^I_8-o?ZdzMFZ3V!~p30V})OQFyb{Q^vS^XQ= z=ZwdVas!B(Y-^Kie%e7_2o3M5Yrnsk2yWRu>N|=J!u)C-QEnAgJ;p<-=evlS=&cl zGdNfWPb*Px$pqow1QNb$BH_hJsjp{iLgsPknjsZT)tiWNiDqH~gigIL02#D_3DvW7awHK?s3Ke_ zc&RqyByQyPah`B1O`Jg_Z9>AN&y)q%wW-!8zjIo6vj6>Lpu*)R z-&yq-+b@i%4C463@Vbm~Y5NBu^$NIlWY4u(D~4K$>x333t%3(m>w8oj3r>*561Hn< zF`Uk$MrPlD?l)k{7x+95iG)%UIM{dX8ts$k=ATyv3*+?mh(U<{v*|(b_?DzK9R%fi zaY2X*H<hs$eS!ox1&J>|&>7o4<93kLhp zI7J&~5+CXXf~O4!=Woln<{7dA9Do{JVID7`Kq;F%ui?I&VEOlgDoH(eYcG#I0cI#Q z;W|ai7b8)vO%FPL>ye)xGn@CPU8~yZ{~9Z)$VseA1ALuzUdCwgF5e1z92va+pmUdy z6Vs~F1}8CsGrZNA;qT8AToSGF-NS*k8mgQh3Idt2&Ct?qRuhc!_S90|=*nKj{}P9s zIhVbt&jgBF`YvnqeFg-p1GH{q!`n6!0Uq4wKH7vu2ZNdV3VE5>z_B2gmYQj}Y(2OIL$1R8pCbWqJy8{riq;b!@L!}=f{y#Jbgndfh zGE|^sLv)v2umPHCVTG7%Ys`n+uBaa~8?G6tPJK2E%A|oL8)qS%9M(;!MqA}ACD#Tm zj&VQ<50adVoI#!16mUq(rGqB$cPKc3VnPdStuD&orDD?pK1c!Yk~OMIbKdU#(}=R4 zpM-b|Hzx`wG#P`<*(oh*?1s3#W3#JqzJ&eKNMp_>S-=jA(mv zQ?2x9IyNN}PM&fJQjZyUfWX zxiVI30ednhbyp|?*Z6`;p+mIlufD1qvHH?k2c|--z*gY!dGd>jF}{-_{F!Lq;6+nC zL6h80?h3gXVNmEr(J5Z>L#vPe-sJ7A4ZMWwT`N6 z2q3Ilv}e_|XF5a;9dvg-9kn4$?%gebnnn2)0;Z=~K}b{-glO0?EmJC0cg- zrzvjFj9ttu;MH}2b6cwE3Pg%oHECRshAwk;XRgkx{U(TZJ^lasR1Mt6Hl5 zXYHu)L&Sx5%yXP^kvCLNp~%%j$Lw=KxH4*uFKDx>7WML?!+Vy=eE>2OSzX$e zZVPjK-MrWTCNl~Cqs!2v5266$M*5+Vh=b~niqx=meYdW$H#&x?epKWlS*V_>XrfX* z`o-cGXVgSh&5b@`{s90iQO{A!mtaL*{f}&AHf=-D00e*Q%97$oE*3v(m%y!@LgNdd zDl3^wvMKMH%O%Q)(BA{RmLRl=>)i0B3vchu5gwyf&ae2FHfX8T+#q~tOIK|o<^uQp zkGiql8x)pD@{Aojma*Nt!`3hf5A%y(s;8&d#MyoB^mTD4)Ss}XlclqzFMv-1)t`Fs z!MNTw*%$P)sxzF*?NE}?jfcjK0244(7&}lU$Y{*8E|ag{5p$K?6HLTk9%)B^r>%r6 zi0MOWiBJU1eYQfPV*OLvN2!9SbnVzM5LXDkWAl#qe4il#88z;8I3Wu`bLNe0{HTwi zR0O>~aycYorDr&o-@RqZd%g$wsw^l+i+u`{+g60|)3r((9<~O-cOV!kp@}k@Gq9uY zr^VN_*7Pce)hKZSo~UPe@UX(|PUFf4?870Mh3oGbIVgtV{nZHI0U8YHKwbcO=dZHC zEC_;NCn8MWzT_~N^2IIZzK)N4o;)^#XQ%NLvVQ{8?@Bs! zN@t=JOE2bVnBK45rxu?3lWk7~XPi8W%8ka6BJ6-y}6f>2N(%g2)I*^X8eT82>*e-@vqPZE+js`>Eu zWe#rDbpsG1X8U*D1{3iyy<*u4_>D#`g(UYj}-r_ z)(Ys6eT93)W&T!8W#*5_bxmdPaILpPoAwSo{z58BfR8~YgD&);Jz97R-Ob96ry(T@ zh$l*7_-&IMPtb-%c&3GoAg}-jMGn0ZT*a*_KoT(d$qJ=IUfxL*p>3bY2JEud&pGqX zI6o3ANSA2fCETFIcx7P($ z2Wj+n^xQP&_}<-2&nxe{8!)5mzHthPZpQzO0vlk{JJhR#$lWO^QxO8isWf&8r^J)= zMx3||QS)VH(QEIE_n{?;{f?YR^|DA_zgU!a8G(Rvv?R?9KRI;X3BQbz{hcv-L%4K_sS^)tBOOEVOxuL<5eN0ZRQL}K2RoLjA zl1Z<0uSfI4qZ&ulB*w`G{(eON)UzEFrCVb{)JGm(cH`*6Qzu~@$=h6`B>UnIxaCma zbFRRfON5Yn#l&0xcj@lC_dwB$vxG=Jh=;g|Eu;uKOhF8|?tr-!(~Np|6BtWi<&TdIn)s|!+0A6W#m`(QUkD-kRd9!$elN zoSau>gPGx$a{?-ZK_r^{G{03by2tdALDGbMh$@QuW_a)`2$qmROYU!^Uo@c~IwTax z%&!%ZS;Vm=3y@$qUZsbmHh^6pFnfEC9dXx{?mHy~de4LeiW)Uq+72KlSg9|eae50i zNrJge%UzoJoO`~hr05)>g(&-v2%3w4Pe?m&jZU-cc?>d4JYvzBnQKU5Go%)cv-wEn zdmvVl>n{0Wp#^_gBV#BUnJTX3({%an`0dEtr?C(_`t&C`rqrlIl4KA{Hc^KqL^`a< z?~Ite&C|r!_tj*y|3J?%AQ*ZzyVx7J=uwQ6Pudxx^byD=4)O2mT#gANnvm~)RyF=% zJpO4yG}`=kX#$hbjRG`<1NsJr4LGSGhj^F=pC7ERg}tIWmy9d5`$RiSBc3o_9P@uy z3ZU3IPMy|_B2K5k5LIx9;TZKw^CXX{+a|oi7za{OA`xC0SLMd=nvhk5ODV7w1`Q^o zbyh|)36Fsd9mFqSe(75P)o>VI#!@4pnQOh*OoOp1(jH0KV+2v&iZ{XJ2nC87f^u=+ z_#j#zLMoz(gP-fszO$r@b=Q`cMs|yf6Q7(l<`sa?>4#Z&fL|48t^No-4YdnsRTBAq zy+Ddi6gE32 z6bDFEc2b2ivBc=HzdX2PYbelOVfr#87GR*-Z=!bLVCer+WBVoI2&$dILARUB!)-70 zLKBU5o!3ym&{sE?iZjWZ`;h?`IQ2ICF|UC!Z_8KLUekihESf~Q_{7iScHk^gICSq_ z?0yYJzSr#5yX(`z+zG8u&>@8UlsZxY*j*ClT0Q+*0WCLV3MNL_`}g5G=DjA8!d#Mc zy9_2F;m7b?aw^d?_1`X|k#(ZMHG~G4QI8Uk;n($ZjeLyFinh9_eJ4|n-Q)qiEftaz z(D6d|MTy-pso2qDH_Sm;%+brBAOAKm9@3Jd zv%XVHV7Gp>!r0Ywd-PO|H0lofJH7|!o&YED;1aevVW}%q}&Pw=gSe1P2r00usp6(_m6Ntydh z<6C}pElY17f=Wr?6}s0;%&0Lu^_)ota;}Y8+@0_3p@ubR(>DyCUa^W=hKyh}H_dXP zRxvy=esu}or(r19I!bbq!iU-#CrLN;qlzCzSLzxscFoq1)dckLsz%`Nw3s;wPphiI zq5rP+!97+MLLNGKyiF;ftmZwj`lueS_CCzJ-yJd`hddC^C+O%CNG>+2oP+32iNY3u zSP`gbvM)w#Sy{9#%AEfB@_2jp3lx&(>kqLxs%vHKU@G?eL#7ZrK>uo0#=qScgeryR zSLy^@J()$bd(89S11{jEwO8JW#fr?H7StRlyNw80{Z;iUxc$JF!th!sl~)|ag~y@B zsZl! z5zM>U=5UeXk9n;>(&NC6cB zIa49HaO!HmjGjRB15||V#x0X5g7=HC9IsJlbkBvNi$SXDooPHr8y<>-#Ph4hOOqf# zS75Zg0v%?a)46lwywYyksHq2{0Mi=@8>N0M@7Ar1-aQ@>|L>NFxmA|1MLAx(G`QI~ z9J%hkR%}JlDLB|QtGyS7`Zmwp5o9{8g6iT!JNP6)*qI1N?-erytcB58;owBwml!Ji z-m_q72?cL;GXjih4>m@iq~K?a`*C6gz+YF%h|Cb~bGjp0AWdlSMuLLVrULA(b@*o5 z^zSyl_$l@#yvk%r7PsYg9^U963_%Ob%;gpo{=ip|i@(WN|I>YtT!;H_4e@Z`62rQj zod*t%yhjA#_7(E4nuLtz<}oIqY z-g&4zVNI?Rjm3;2g3&?=rzfK74G{P_!=xhoZe!+)_5zqaxB%Y!Pu#Lj)zoKI7wGLj z6g{}W1Yb%3!odPrktuHXDaA!1Bq`QggATFnB#VI@3`r)<3Dht&8WV#?3WNq;k>_bSdXUi1*=xs zjjWa{QLr%W7pG$5B${)u9wQAdsQQKodce!#%X~(o1*gkbC+nb{AovE*&Z0I2VUS>k z=kpqNPyyh_;5LRD;GBmmX^dze z0k+v2)x#JIYLI!lv7(`!@CHuv=YK5h2$+|Gru%^_B3GcDerDij;|9vyzE}E;?Y;)j zdHvWlU=sEs2n`fT{P&>c9mv*%6IlAxVud7X81I}Dw#qqsOVQJzGQ4!kE^b!_mt`w2 zVXE$~C}M-q^v|B&2NYn#ZUcxVEAObh$B2NBf&p>n0VOX2|0N!kL=G>M=KX90XtL8# zP&U?g#~ssO(xDzL3Q!GG0>nr`g$}%2j8PA3dt=_=SfxoHCOFRu*yK|V{l#$m$Q7Ua z<{T?{W6X{A<_GP%$X)a_kYOKy( z3EZElHkkgDQoO%ThNHS}WwyspUE{j|iyrsMkvS>~oh7LwxKVN2MaeK(#?4;N50srp z=0CD0LYK#_m)?MfbBN`#Rqsfanh*juE^paAQ!fLC^(ZkhJr9L}dLkku=QdC%7+JU7 zH0_Hj(86i=bLkmxsxe#9%loDfAaLFewOQmP=7r4*<}P)2!Fm3)`t|acAiriS?P(X_ zv@1tI95Ke^P8siQV69JCoeDBl6oPJjl9 zY>IL~uYG4Zz!o4n>Y~Pxh4pHfvYF(RrOLe<{n|Hj7*;x0zW*AKHd>pp%^mGQ<{#dE zLB$lHdi>eSblYfm8+O$6uLTkCZZFSODBrdpd`WmD}|H|}Zq#jDzYLIrSv8%tH zBnG`~^XD?>vpV@@>ll-#d{c{*%wFINXTBCQ&>=DdxXj3*U*7rXX>(CRHVqS$@6>dY zpcH%9Ke~m>M+$)KAN%}GobH>8Q4lZ)BR=Y1rY8@T|JRk76A1N zXX>-O@#Brq;0U*{!&D6K+LL2nP&Q?ejuiakbwb~^jdg8^jZCH4jMy02B;lCPBNF;M zQH)OYd`pse_F%u*VkZRcE^F^I8r8@BDa()YvdQG6B`0iJuL*XjX*XqRU;tSBXDphvxh$)w{Noedw$ zbEXI#4L-!4BULh%yNW_=UgFx8_)pUXaABPM=UckO%9_UCe}En=mu>aA_|l2p>u^?o zXT4RgU)W_4d{6#qxbutX*0+6OIh;hu(%+Qo=}NGM9eVqbWXv-1iDC+nK{$0Z)UBHH z)7)OFbJ@cj9je)6r=^`PNSy0}QR>l8A<#mFMv7sOPjgUlTm=lv<`A=(7giw z!xP(u{ecAQw-QiJ%|?6}h3V1D9bp<_VF)5pgD5;?1(G3H7|i0=RfXHJ$2`~bUe3)$ zO8bra@H!}AAa)V|Hpeh( z?qiHptLJvk{gx(em-*xl8%S!~Krs;oUL!LcQom*KVP5ik zn(mzu6JpiirHOG}-PDo5JtUcivXqfqeF)y$lm5)w2idYg0{M=1^VudWPvi-Hy0qEG zE#0ki4DZh%3JNQ9CGdo&n^}Hj!;0*6_#5IR!Z+klK1V(~TTkWyqJmBeoP&sI(DoUq za+8}0LyjOF8X$$*lyf1zz??0eZE631!9vNRP$hs)b385NnkPpKp_yi}%N{96@4!GFf=?w{yn%qvHY?!Mi*88;sDLE=VpUl{ zXHy9QG)D`6wM{wnf(c(kW|u?;{w5*#v;(dTb;;^SYHpQQ%*y2hu8To?7Ax1gV>A zRP8u!`Or&Usao9563?c3FPAbxhFQ-iATuyPO{>@KrqPzT>84oVZJitCgYC*voAC8I z`0{7)ak6-Tp+dt4PaK{sP9oec(sGpexWOyplUdpG=eOI2 zWfG>#gSn8u2PwQ?jZL;R1;tsTqPo%s@uNIGD(!06dAi%Do`gJ3*__6Z3@+98ROF|0 z`Lwn&q1pU=X1#yVVz0L0FDw0N2SEM|Imk9f3NwMe8LQ$i^f^kflUc8RLad6Up^9reClZ(X8g@NBTp zf@``E?n%sb6Ze+|vZS^w(p^sQj9756zkH#?64|);k2gRNG!6l7!A&%lpC?t&F8|bc zctjV;^?xz9tmV0jI!B%dH0$x}sUH(IfdljRhedY|QC}2D&A=$egG|{ZkSFGg2lz(m zqoUFPdj>0^c{iOAX1d^fx!DOAcz zDPWQ5JH7mE=f{o{moWvP1*9TiOOjG1gg$`cdKAj(gaF5$F zH@#pJrl0Vt-sSdYk)W-lLsD8mx(RRoou)0}u6w?=w27pkV9?M~+5)3RK zZoE^Ew9WgiP3=^=wT_xP|DZy{IxSNAg5MBLN-LdM4gdY7TeX_mS_egWJqA!JRv#Wd zi0v|-lfLpUDwUkJBc|AIUp)`CyV?GhM%Nd5Dsp=R7yy0VXyb5%yBI4}& zB8EV84KjzqUL9|{r#ZRWLTqZwHy%uTfXq+i1slad-Wc&3s(hVR1rs%(sf6P8AjX3w z^~afK@|T3sU^ziXVX`D5DKY}AZ;SQ;dDs~4j153$`(0DJHwTl6A1m50THAw zfm^5Ikdsn!?2j~IR#wb_4I$tX4l}5^yIe)uQ|m`?`w{40Jq$4M9ULE1{Pm+NUbsTf zO>+f@p{OeWaeE?(G+sA-LDkTjD?B`Zi3y#W_o`C6}4K8#3Ax_Je8I9+A$ z$N>{krG;VPYzR7hOFBG+cv?C(rFuitzdCsN1L z)Gw9Q|G@3@lM+F$QD_07v{f?w+P&xgaB}D9o+JnQ_mUFXacHQA0Sh}hV7SaUKzcmv zu=+jSIb^mt^lVmweTluW;U2<@q2wOvk%x>%1_!0dkgjA4X?@wmGmDIQWxSl<&mhA~ z$NKtA8K83medv2whMIu{3OM7=*jqbXj65n^DH@N&k9xq;1^oD*DqB)xxOc9!b_Fi& zJSM)v&g$~Cp=kkp=LrKw3Ecq~6sWF)ad&uzseZYKe`&kQqLbKTsGs3vH zBRy3&%X8-Z_V-k_*as7fSW)eU=8YlGxQJ44*wpRU!&4OomhM0!TcR&XuhR7j5DFEk zUNV^FfrDM(%K1*({tqA_lq*2y=IH!7-}_JKTA`Ut+yy?I_|X)1P!) zb9b*fJo7LFmOWg?;RcchIQAqQd;NbPM0rGBlVZIckC_~151=VnBT28>`_@p)!oek* zseWvhxmwj^dBhoq=2x(`fxX3EULrx5l+%7HH-W8Z>|n%(sC^zSz?7U6Kh(l z2nnpN$-1)rb^5o9e^j}?&b3DI`n(N*8k3!A=g=QGXsP~W9rC$qfktP>otoDsuE{v2 zd)T@Lbzq1%2zL?Qm)~|8q;L5KrFONW5SF}2Ctm^TI_k2o>3K$KpcJejNm{1kBz5Zm zQMlYuiv+GEG3W{3@uCH1%z0#g5nO$6$j&8s)U{)}@zi7p4y6n!W>!cHO zFj%c}7q2B1<{!Z-@Z7-w7`7?PEfzFDI%WzFe#q6oslCFh`m8c@dndGEAi06Qb^&cC zA_uC~uk1nHXw+|A)Qeix!ZE+r`I4S3!^>)ZifIF9M@`xID86b>*8_Q9jf#g#_l@#x zodoYiNp*OJW@(4cO0#t1Wla;pKq58@X;p1Vza1(G&>@atc8FcINbGUkuhci_1_<+ zpQI(6w#A1hD6?FS{j`?TlG$vo>K`@~+DOfh)t&jQ zlcl7XAna17J?IK4(Zd8N$l2|htpKIDMTZbJD^Kie=~<#nN8#~7E6Huw5f~OoM~c~o zmZJ@=wi?hkBwZur1a)tB^-gW#o8aV-Unb^y9$pw(JFBuB%9!9gUF z3+hUuTVG7Vjg`_S0W^ca)F2ZB^wQGpSEi<>gVu%kBU_Fi<^ns%Mkx!54wQ}-%BT5! z9BauuZfxz~H-ATf+r}luvk9-eLTs*yEVQnT)Pe9`qMm&@!jdI&#umHVv~p%n8e2=c z)4a8emAte)b#YIDVPt=iJ5KgGt~ugTf_J0Pb}c~kVQw`lkG=fkF)Oh@Iyo8?=zSj? z{*<_(@d^$OoBJW>B-w+OS?sUwitdgj=$~+v_w*wzn%=Z?IgvO2K*-RuMZypm7ckv< zT3Ry|uv{s6zP-w!b3F{xT{V<-RD^=IOb2--x!k{yfQ@1>gI*3k9cWfFV4)(uYUwdH zE^S#XDH{~%TvD8);RonNv@aaZ-*6O3C_WyI3^e>?6q9;aBGP{Wehs6RL}Kf zoL>Q*<4GMa3=?AdG7A(IwG)vW7r{9o2?wR>>T+jZhn9&gdk_+1Lv6{VtirmOo09{3 z8u?3JgW${AMaG;fr@UyZC5O4H9&ZG6mA)qQVdBV4!b z*lYgGln_UdSSB%c(!2^uq4JH;b%Lbu>{9a7x6(l>^kuTnYQl)EpbRacJ5(GbQhru=#`XX0UW_TE-eMUqbe6XyA^2)cv6(kMKa=h%si_j)h zj8D4Mro=%^VM}UuwJCeTbYIU}n5UIY-X$bwhCe76s$Xc`;e|ielHGO^aG~sLvZOt1aYkVXuISl( z-euncY*DvOe7SeYN)7|(1XrXjK61+mYOWerxnhI?(e;xv+Mb?TIcLUW-Jt7$w%n+v z=P zf0iFl9W>KXDNscEnqxQTjrx0KE@Zj3yc%{+J^30J_fYl)S@;YWm)mJ)3&5t zxnDuTpY}99iuk>DF$eB<;#b81e1sdb1O!OFdF`Y^D63^ML?`AgW|@8P%j8D3%|3Rr zbo=ws)IGR7O%g;Rz%Tz}o7%df?JN#sE}1u_gLJR33Tc=B7ilnK5=~;Mcc8U zPCuSyi@xUl`cPF2z{wU%QW+G~hfcLaF_U;b954`>F#@ST|HIzSr*ZiYV=o}bu+8tg zr0_##I)<=4{BI4~jEoRp*=JCXuR!~mAG(jZw0eXP=a+6! z0IMfe+II2^jCP7tf-N59@KEOS)P;O%iX{ame(K_WH{O4uSs}V^7482&PPv-Lqbg4x zl*lm@T43e#!<_<^kIUomg|4=0@-}cjsznEF%>P@`%4+oIAPB?~JFosPJA7?z;%~(e+G zF&vo>BLlgpl(^g2}reiuBMD`3M_GSBl>$^pcNG@_1?NB`DS=0|0w;0-8ddsPN1UK!iPKB*sEh9C>mj-?W8u+cBfh z+h|$6B2qV$b_8FR=N(M`b`pNy^C-VzL{O;%P3>n$)|Uv!5vwu)XVXQbZ;mQ_jF6KT z<`nz?Hy`a&WKhv+2sk4|h!8jXH|S?&#oJb)-!B_4_-&Zr>*u@9{%E!{-;KfhFM49( zw)2|c8Sbtop+!Etg!s6!EWEV~E2sr)Os*a&W-o{?R_RqrThygOCIN__`5#`SsoGx} zI}d(b;2^^l{<+g$o&M~*NL|~FBIPS6&sK?52Pyu31MYUFYiIN!mHAq7u3^Yl`w$X5+XM^ z7i*B2^`n=@fTLhk4i`In`_M|G0S`Gksk-pG+-Q|JhyOeTl3T79D+A#OIB;m4&aS=0H8~`;BF+>3fN`XVhsRw~M5uTz!QXa_)ni z&fMuf66lIlF=J|#R|`ktL?(D0@gXl=kGY`TH1o z^moB$<%Ds@>q1>1j$;GUpT2E9|593uV*#e}=$ZR~L3N;EKn1oaM$Wulp# z*D$VuLLj5nU(&_ijp9tbV!)|yE{fxi$L^+7Sz&ej+5oPtifMYvVIoNkUD&1!2t+f! zdezCB)I<+7cpq-6Sm6xENE8Iov(%1OKJo_Z^nMkrUbWA_# zNy=6y-`H0f6s(foo4HWe|H7wwxh)OGU$l*8V{8m!l=3-{dtg)s6IL5UlUq43W6OSJccey{%2;*hK14180+fPwS z-ly@WNb5OhN{)rN0=7FncnGN7`d=D-yY%4s+hFocF_O$DJO@`eznM&rR^P@iTl2v) zth$}4yu6lbQl%nI2I%&?yM3%8bP%c_g;@Cgzdi%igX#B(`-_cJght{^T6(H!g+pXD zP=fXq&r!&p1ZV+sOL%kxJOSp7{-P!D3z7YelX;!yEdPZ3cNMpDmCOJ%>-&mE@D0F} zG)6W$kuLx!<+2va0_tM3`H}wnAl@UWom--ht;?L^+5ecW8vNkT=z}c1n7%fIDQY!l ziORgofT?02BF6&I=H?Ai{SSU#;!9H4F%H<0rIWsd@!P#pGa8 zFA%0r%j_j5aAs^4(O8a{&Qqtpx8WM4?DCREEVGw)@pvwI%ywH|3#L9PghdApqje!n zV{XLq|LH$INftDl8=iS3x&bbF@MgPWc6-9N4N0~{VEhKqIw2?(Q_e^vCRW&tEu~_1 zQ`^``qq6(uE=jE1pQ}_?5wr7U=20trT&Ak3;PvRiL8iR9RUfI@|G{qV`z`<369r#d z;E~WNUKL&{nRcQ`F0!qPE6A&w{;nfrJs%Bhv1!-Ioa$`a@Al*L3`jj+Q40_86&dYq zNQ%>%YKWN3s+FkJa;BmmbeX(l{k6T5PkA}bVlu!Cxmp-sW%+7O39WUMpi)|79&WCc zMReH&Ecn9=mJ-u~2G5_+xw(;Hk|jkt6>yti94nnEXl%`Hv*!N#eFovV=wReChc6gf zVhyq?^UQiL8p0bt&Uhj5pqH<}0p;)8taR6+CM5HLZncvKzkw92okFQ~_e9 z9c`<60#aC7`9BONFvKk`J0yFG-F_B zLN3N5=ycl3g1nlLCjS`VYVOzXb?w|jj7R=I+Ds0$c|o5#)>c!lQmHZI%j-DZzfeki z0BNv64~k(u=@i3dq9iRwhe_QFU#@M(tX1rkVQl8e)sVaSkw8W*xWX3k)F8zIEm+}& zj{PGJLMr8&`JA2NEOHntq5eRWol00E#@Tl1gv^xY-NFiCggh8T_SIa=SK^l`U8>{J2iKmiJvmj*pDpsK!z3fOLr`cw?=y8QQEoll5K2TaTH#M6E z&;@bmHAK#r&GWe?S=jZ9=1|Pb2#V_E#}VHPcq_4B;QF*!+h+8nc~59(=b=I@-v{zm zB<9MDdN$!J;LIeL9Ox5xQzKv?4Yf!J=Uq!6!AShw>(qKZ{-$` zL1vbe0iQJAQ-DY>IZ6J1lYvF;3Yt2LRm(tT$Q&rMQO=bWD_qsxJ7jw4OB*HHc4jS* z8r#W`K^k$QdN>%>u&!LkF9@-gHoi3TtC27WM~Em&AX>BdSmRCk{>mi3>;$aU=-K7G zB5XH~enRzEU~+%`c{* ztm=Q^sfaa+M=cOEQstxSMnp?`G(fbuLPy_r`b3utn(bH`OtP%Nkss)_1B1+(jGR)h zNqW^4i;79?+Rf)Aw}_S8Ke2xO++y6XQY}EBswccAGl}mh;6G!g`SnZ9ZPYlo_#GwetB`0m7SJ zIJB&QjLfsi`b=hz*(JqZ<9bTJFgrTNf8>2@C6+kEwC}XpOx-1yz%j%GO&$&! zi09a6?_Y;~;f=mz=t4N^)xZFCNYRmQ;k{kI3y%}bSFg-?#7MOMe5){`86$uoSHNP5 zYzT@y&t&zN{C}grD&U9+lgK&pSdYLYMGW8WatCahZ>g72_ycb(4BZuJF)i#LEp?EW z))7I}ZCcl4iqSEpgNO=&v300^5-qg+k0q_Noo*+10?LpyvQTBK8~(2ABfpm8NLQlI z6uZBjt@W%q3~KwOUBKaETJIWptf-&~&nd4?R!v}9o)tK4+rOfj+1gQ6?>DJt3d%9Z zsA8*+i9H?^S-^A-eD0@QT%-p*MNe7TS@t%Y9}`hmGoKEVzaDCWI`h0!%^~lSw|jgw zMmFcN_@{pk2kYYSGz4y?Tx@nX@!ILikv$hKvzWY$Z-ECFa`4h0JKzz{FlX{eI}rmv zdIL8_m?{t6+Vl4cniKTl&C)YeWf zqt(XOeZeRo7dPW*4>243>DSL`(I;g8{8COUrQ4x$`IKEZo zMoAZ!TAoKS%;4pw{H!6ltP=eNsS2Xta6pfs#BVpHeU!?mzhyDFgrY;Gw-_6Qm8SL{ znz59gF-BqMg|2*P@m?HbFWstas|%j}v^sHt|3;RP&q1SR4A#_qfd*BGFUcmez0m9q2;SE5*0&0nstWSD-^6)m-F&6N)g^X>9^ej{!#h-c z0Dm;uLdk?v#|=$Kkd~H7DJy}}U9Mn>DH-SKXIJf_t)gK3cPZ z{Tzwmi+RMwd_4~gT5Ra;=8b3hn$eUP)|yn1QzudBgh!FQ?<~Mz|uy} zGnIMGm;*GZ-8%-<*uKgich7(w*OeugK++FLVnSE_`BcUjdNmmAoWQr=OIO-A?kt;7 zzm~!+aF#z5P3g%bl8%Wy2z4!KY9E;ZE&+iHK;u7buIz={UUEqP37<+&;pjGiO^U2BuOaAFj9f9hL`ui&tJh47HzZ;_IL@|8|RsX^+t*M z@q_K&?50D4R42fEwVp1cAKw8<;stiiHcQA5J?m(WMC%a@_mwHN&OX^+%L`4gDHk@< z!$RW<$G=-p8A*HuP>yGj9fp?Yc!1ML>9fP(Q&A9(yBNhV+G-V_E=xvfV(yza>_uo5 zMPJ2W%9;lVGzKPEpcZ$bV3m7S8A?#yD)`A$zH&T)8`CA|+@=CmhZm?ZmnOm=raQ1i z+yH9XL`Tdkw}j<;cyUjGMfleU8n`ELf4XnPlegcaqtl}*q*Bx~ARN^~rnDH9+T;fxuWFL7m-&hH-us-g4v>y(^JfZ=#%h$wBb zO_(=X&e2t9Y${4SgG}118Oye_Q6p^$tUCN(O3{vHS)w4#IyJZLmG&!oVy~Q!GS^Bk z>wEYdlbkGjVlJ@H8^8)uqHY(0--qK$Qb%XTGd82)xv?hpP*BguF4tWLgzsxKPY zU;>8PFF14YfgQg!Go%iSVdd{Hw}Bdiuh!L%X+?=w`q=!<`m!MhJt3p+XH44(7k2t< z{P0ii`DF;4hpJ5wjNG*r?zKot zC}|~(%cpSBqYb|xLuer~UPVl$!UeCgMMDPxbB$#K$wJ;^bLjfEe#;@dVF2VDCq z@m_VuSzyzikhNbR6s?ePgs@U8TEV%Te26nljL6LA!Bx_LFhR>-O0sRkw=C3_Iam2S zSs*NtlMzekhNGFv;p2mhTNvtBF#Bb2rScu++vayK2Dot|boNREc%hz~#-^-CM)lA( zBp0mN6c)3&e;M_RpQYFMB5Q$6LGP{d3ClnvUpDd@gV?DFLqNjYkHstF(}_~UnH>Vl zZ)H1#oWc7fF+d(!gKf&n|9fytARj5&*1jk#$Ld+GPdXriMkX}T0E#LWSm@U;)8c*!ME$Es{Qfg4))CpGny1U2%h?9WAXQCU`;)i$>@7+= z6&*nLGP^-D`C#!*Dgq}W&)OdX;Q|IvFqHe)vzn7j#|nEwglT=3v~{~^H2(ilTna>-`jUNMO%SZlTe#2i9W3AblMhR}ibx-CHcxHJwBMmG{t28Yz|v zkX%pE^u=&|g<_WG<)OxhO9SBxlnIgh&8EwdBZNR{_;&2Q#W1Fyw}Z!|IJu_w!Ro)m zSTz$kiT{!ido(_SDDA#p^(c>f6mks_QWTdMUd@y6DGq!(3oC~a>EVjRuzcaFWTE1d zVGb#Cqnp8DS06YgJ3^WX){qt68qTM`ztOLp`OG6Xi&|OeT)zIJyG9P@Vo^eJ`h|m( zN#ichQBb+{CM9$)q2um)$xjg(>*Qmb4yxvi_tYkh&kBd;hlyjpqXyAMPgR_Lh@H0S zKhkI#NYasL2EWKL;;w(E` zyV3|!B+Rkp4p_$Ome0nI=45dLgbkn`3lpctq*$|5I32!a*?=z5t4CI3B}RtpQaLST zes3yz!9_-^CA&KXZ>_S6t)~7JbHg5Zmwzae*+&31y3El>RRJ-FhRXx8Kg|oR}Xf z`cutB_``>M860f4j&zK*H+;W91sy??>5_pL<|a+19Og%6j0u{wh`9VH_nO{|hG0tM zr7e$^Knk#E3bp~U-_JONQF7DzEMGBfA=)sKgTPsK0R6hY&llH{bY_x~@$_YJqGzGs z==u|u6ODGtivxl$ZiqF2W3GSmv}znVofpjWu_8xsjBpKcV0{ls&nqgrz=J?b;nw}; zXQ_l}|1Y7823P>Rqjb(-7WJdR=U+x)Tr40|oee|J0R43{8`jOM6JG>HPgY45WgOLA zngd)D&k|_7%u8%PAJe)`Gv!9T+gtiAzBJHl12aqC7mp})4!&OI)%X58ocaXS`0P1W z*|AzR2RfxEmlY)wTMc>Fn=gy`JKAs|lqobe7-D-)CyP;ZA8qv$U;KLDHxG;TiYD?eq9Q)v~NCXBGOI}>tK!4=cI zQ1i*99=SwiGjYXQmO6cInl(5(?BytBgj9bC&psA18Z7uF9CN-jG%HE*!6AkTB^q-S}U6DeeOEC(n2?&6wsm(UzT{YgDB2USB6lM$kpK zLcXbO{xHCrD6(Ec}8UcNr8~85Xo3whpX_!8rwI`fD_a zL8L@%mA!$XYc5FlkQ*n#H*8?AR3S1Y?~vh&wSHI+&^v-lsLI9}a7r5r;{-p=WUux+ z)PpKIp{+;IVRKiK#j7hJh0bum(0TU>_WiRJZWH7sG36#wo!7M3?MGPLZFd;wF%@#c zF4|DY3M8$BJn|Y%B>MNs)wy*%EZjy!(ZF)>Dp$|BDf`K+AmnU9**K#Q#HWtWMie8; zDJ!sIxfM5EFkKf4@8kBFLyE|n{ReUSnKeTyALFdUs>J-ta~k|I&}gA2t#@y- z(Nx6l8IP@|PUSnKA^aMg5OXI@odriZQ4Ba|!Y;azV4Il8KyU6bd2$+H+)|TvU1xP& zQb8|(!PabSv+-Lnz1O?EYP8Nqz~)%+{LxbLUO@&HGWT*`eSaM;LA`a;V=_Fp_c`A` z3Q{~hcG%@(vw#!6JI)zF*yF+jwbcc%Z?3G90(0BPYV!>tQ0#XopP@XYn(JSWu4j=9 zh`QQ)ORH}sgvYD(9FALlc~b;ArWQv-yV+}Bkp>I114N`#y41;VzXYz&h)}*hPro_E zUG<`+`_4j%1(!~0D!gh%%A9mzer3hnCK#e!fkpz`GHs+CFLyj}FVzorq4AkutkbHwENk`(&R^YhXUFg3bgXCN~%V z!)9O6VSo7s8U|jmT#*75h@m@0oE%=qj%l>M*KTqTZe zd1kltUnKp?^PynC_TU!x_@I{B_#RAiT1F0Z#*g zuimjeBK$PO4~=~c0D>c(2G7~*3{c4r`a!}kFQ=7L)I2FXCN|MgP|M_+!zZ%K zJ7i=-hIDzG{kb1`IVyvc{5kLyeT$)?7h|mTpmK4)NoSHo%eq9_cUX@jZS_3~+~h=hmV;9!Ds6a$Paa+bw%1wGGf_xowwl~!N_-aAdP0sqSeYzd z#*G(fYgm?U&dLhF^#db)BBY17ZQch|)B(&Si{$J7?+g3Ht~;CHGrwEbRbwH79nM={ z=$ugr_0p2_PsM1Iv>=H^FzmcvA}Tq$hp#!JZday)-mBkZ$o}{O`G6Tqu2C2aNHk(L zz5_Ntdv}e+f|%SVczv52|Tm+{XhrQt9bMlN?tID?ac)%srr>n%cmZ79~8Q zfaflv$4fGbZF z+UK?fjcI+wcwy(34)-R>on{dlc=^XgukBe^O$PkN_8M<0&fvRiL$W)O5gMovfE`vQ z@N}?cmY4~y8xo~t)v5ZOTs^NJ?s{D=d_mgQqX#g`3U*n7=s*XKX- z9DWCx8XAYoeRsq<^P^`s{B!ca&YvmWc`K~!_Ei(>9vgX1CzEQ4J5L^K}RJ_0SYd@O57Sr4$5~5Z&lAls~3TK7UQz0$r zEY{CsZ-jOFW?VkRtzAcer)gOi1K*E&-hI!(uoMTMx4}oq@od}2UY5ubXSlL|ve)Saui0{)0q6H$-itK(P1maM^(zDflxnU0ivX*t7SJletYf zJ_Ra5AR7l+9A|=g44l;eavAHMz+;y&g_PZM76Y8TzS#YWk8l@CCuntgh>6!)K6Xg1 zRA|ek7%->szwJ3b>d}>?7i1iRaVh0W5PksRv?3aJLge{{Efqtv?)R1I zkGPctt?@qRiz;+TNZIf=vWupFa=wHIk@oXd%#4%O@K-Od3pgUYfzM|IfDV?w5=O9N zO}X_T_OTV~^^i#C+)gr_pBO)O1_+zH4 zE{F;rNnR-sr0N`1i5WOQzoisZDJTCk94h`|*Awwf7|^2hK85yldFt+1F6j2u{7I6y z#rE%QCnlT${p{lO2^f3>Z4sYh&QZ^_x)v0A_Hd2&R+5w!tfsEbzl^)VR?NK$y@*ZK zS(_EwZhA#O(S5rFHDKxa+GxX-)VdM~i1jvGocn5-&$@3*iTpw-xeb->CcF0a<*=vr z#`g&`K_Uzm;92~!;?~1r1cdcW!orz<7S=L8vyR`x*tn|);Pm6 zy}UIz6MyC<$ts~1Oq3;n#3Ezd96_X+s>L8(XWwNwp=H?=Mm=vPhYU|rCpz)dLFnRl zZ-ec+Gc+bs_sVYMe|$Fyb-{d}!An|%qa_fUQ@})nzbNK2`MbZc9293d4W`z*=Jr_^ zSJfEXY-2^(H-4)F=3t(37lVN^CO3)-TSrkKs$TYila4eN@fbTvGAVJ1uR2srw? z9L`h>5;7XR+6O)vQ!Kl^cK7vKeZHqRR4W1WBZ>~vA1R{2A;eyTk_g1^gE#$)Z7Eh^ z7GlKm!O(VOBzN^O11+sV2rv$N1Ig_JXPhfZrqac$hH@jECl`+r2)efTuzPo6Jcq!$8Zp9r1lFIVm?K#kk+Ec8_J6A4nM!m(67Qq=UdV9#rJYF>NnnQIo0KhPq749vcMZ062Y zHk}ni^aucv%`zx=-`?#?+`ThzUH2{_fr(xL^povQHJ!PHdFUoUUIxI< zoj|fdm`WXWeyO63o!UoZ9TDv-)d~49WraYGp;c0kbiWXVv`JOpe&$zmw=QG+MBn&IyY4&P`)wLht5LYiYZLLLg40V(J>)c1t4Ed*T%41h?m zqcX>0lVOZW!@tYkPeM5ADzNuxZqz%^=}vkJFj{s!Tikb|82D_T3DDE?b^&IP4QTHR zjfm*BZya(fPa&<|SP?Jw1}wt@Y?RrDvujps>8v-D)j>HVS|;*a`aecQLXULFQWI)1 z;1}xrF59InUS3E5u)Yi7&jn3tT3F$zuCg#`|!hZBn zbxAMktjuA?OOI2zY@O}!!y?H)H}VKCWIXxKO_7HWh~IU?JUQSg6S)2GxM&*6)i(0+ z2U;#TS7r(;=&A9k5p-qUBqHqKmT>8Zx;^a(q>re;G3QR=W#x~T!%>YWnh<8PV48Ov z*)6DxmjGj}7#;7%h~oU2q`|2|tc|ap5MNu;thjxN$?dnS$klPcR4UXwQ=UvICue?Q ziCsYSIcdbY{w(=!jKMvV0HEM4l#|@Z`X+;PEp6k8(gq!+VT!Djrf=62%qz%^(aZ+t zPa9Z8Vb$`jkS?gN!vY@<3|aNat;4Dn%CYzec1x6gD@q4viT3_OnLoV1)Q6mTyl6yZ zfH>(UvO4eEGJsV5*+i_2ZqE}_S$5S!a(vF>BOK-5x2UMPr#z`!3MW{4pCV)*s>x1e zF{D{Fg|bjI;vKq%K3F)xc%!HtIun*IYvV6mPZi`n1!p2(@n)ljd6=7_@b^%%jf^wPP)s(xymY>xsW;2jqh=)zk{<2cY0+Dr|LoK z#att_%&&G)m2kDr6c{PP1_Q)WbQL$q`r9Xp9FxES#-Ajek~cQXLWR*$(mXOo$Wun# zcD&buu3He zlA->m`-NQ+sDcafinQzJfgA*NaT&<(QmWh9-Q8r9qHcOI=P=&azW@WQRp@~M^u$Fh zAZO12kvmaS_h{t~R*{2OX&di3!P)b0UjAgJtke`c9e63X!kXPD8*Q9aQ?Z09EHB6?Y{G<z ze`P*erttQwhG<|=nuMcO0Be`0%00ZN|F|9C9(JY2t>B0cn;o%X7Sa3{3@lPgLWP0& zgEx$F2=Oh+2ja4ou8n8^dGwDA-Nl_lD@Q)n57T1DG`R8$&)mcVtF69HF?pqRVKH(X ziJv{+&wf8YQ(*JX2Yd?r$)=NoO~W|tq~eEVq1g37g<=@?-6tLZj5m~&JrT)?M_Z2;^Aay=zjlSLUirnOOo; z)^TsmN#tD^*x%&0RZo)d;*p6``|4dlt;3N4*>Rmm7;XYo$}&hw8@F4b8{8B4$I8xG zew&pJ`g>?UnyxoVsN|y(JuLrECQ_r@COcQORs~FBd;0njK;U(^T&O522q-dOcELhf+?^cB7hDbQiE zIp8Io7m=uN=CmE@xH5IPiD2_2b0BkEoN(h?R~XcF1)+b2TI{1v zGJ&i`8JaPQNsR8gUtv*GooNLi{Qo2{EAD9$7^@GnX(Uf#PMEmeDPsd-BKxmeB;m)V zy^?H0?eS))z@dTW0 z*pfoYvncJyGt*H{WLyxyHJysYjA6Z8D;ePI&&p%JzPd>gvnQADQo1t|62Lpxem`F> zsk1T$9~5(UZ}+wwfx?tt3E>{mNu3ZzumLKcSlY1UX|Ztn8YLAdWe3S2KVu(wfKxH* zsmh`KkOC$iN?7kYAO<Bb0Y` zSDLCGT~zNm*4Qd>Tx}|R^G+bD(a1xylTb`g3&U@kfrvLik2d&)9w$p^CW|tS{=+9P z+J9*bwAhQt6p{XW3t@$*Zq%}4&4odbCHFp)fs;C`UIfHRU$v(`a#9FcAQ?5`!a0r)5;W`Frav(M+&+=@oJGA8L;zzM z8724B^~$(I5gOdnUq51UGjFJ254ENtfFUEJVSkm^z-<^4dGQ^6;7@*@yg(o}vEtu$ zr%~;uRa-9NO?%gGdsWWPi~m0sYGlN~mH0QRX~hg0ZPjjnnkkYY4h~T~C}g|^b59^C zmqh$4bFbOlHw!Y+Q9DqER!GI+RhomfBxkB=;m*JP4jQo*8`rRRnUN+Jny&|<2WV_W z5~jZ~Y5DScqg(ga?s-^FUKgFZ; z-o*MqtikWi>0G;S5z-!63&BIc2Zj!I{UVEi^TJr2XyLm08cFZ2Jfl@k2!S$BY~xqy4P!z8FG+KQ)3+!v(;_%n)=s@{fmED&LApD7ce!o{*X`b(-H**$Cz#LA4p zAhB)94z(6nxjaejC^W7KEtE4D+_(!$i?=`qCf|SXq|}(ZtYArNQQXcKP<}#FpA){w zU2Rg(Kw?J@u>BZY;WAM)xcFhE8gXT=-x>y8!DO2-YGDW{465#QFKJ85{J+w)%+?s2 zF}59NHpeZkUZo&&A`cnTS$RIf7KwyZUdKv)*XH?*x-~Qd9YgOjAyTOm6|lrTAXIHK z+R??L3%+mSr2Yq>+@_HFy14WKnYXO(w8`aJ4}$u_$LQ` za+y^?p+H(|4iqWAJW3a?DaP10>CkK*dbK8%+n7x|@_>Rsh5IUyTk}|kD11H~x2Fjn zc{s=juDL7Imm$d5gPzg{AeW{`oit!T$H*FNNqP}qdSe7FUo9GE95nxf_4uil`DHvDw3dsB;);I(COagVWzq;=8Va6-|7F;~#Hg*2 zViq0!^EO%L2ZgJF=V!h2A>puVK4nt$@klqTC-ct z6Ldr~;h2#um8&3^n!C(fPef+)A@|vw+Y8F7g zkk1IRfPB|DLmMkE3h6JS1(RXZZL15n+$)(K{F=mgy5`kJpA^g5ey!?Z&-KrmOg`w6 zU&mVmo2S)l9)r~{(4!2e52)VTnLnlh>T^5APrB7*aRH{Rwht1S@4 z@j=rS$`YEt<8fNSC<87>QKoc7`@=5-sU?5FQ+aN~2ypejs2cwcG&0t}<6BZ~?y-%iA#)D`jWWPYV=SDs5>-q@`rCyeMl1}1Y5gqqs7Ps}n%wHh@*<5A`b=WMPy8k-0SG?q>>#EyzjqwB=-D|M+yB`Yp>xF^+@?rv^=Fk`H zI-^GO5S|4}|5cf~%%MON1_;tt$6W81yr8Bt{DuV*fv=pv*huy3ySTF(p+m#?;u6tg zs*6)yxLK!SINkN7PgE$;_%Xoh+uY=n<;iOiUfl!Z*9It@;OJ+&FaLvL`L zI#X|=uG}pEWoN}$O!%mxu^`@AB51%7#BKy>irRf+VaEcj$<2^xpRc)@hSn@6{!b=K zVST`@K$d#JTU*GZ(w#RcWrLZJXFK2OUsa`S7o7BZ@445V8un0o79<4*do?8y{R|sz0bNI5`%pT6bnNRV1*jVK6JF5D3?lk zH6jhJ!$)v~q2F{LLV_>9hT3d6FA1Aoqa(}knp=9sQS!2r+_FTP8lB!OBb)k3ikdMT z;Vx*zWS}oSg%pkb9JxXELr_Y|un_u(MN`BMW238j(HSAF;2aY09RS3PS9OP`^qxBt zU}l=*ly}1V`=qHkE~jE?2L1(st^2hH)4WesKs$}zR}ccRY3~Hw#&&^~XWkQFdDs9F zoJ^Yw`9W@PNQw@|4F$`$=mBrWL6Mbcct++RKA`PDi~N5qdjD}R04LI5m$EIHOmIrU zcz+QZ4J)oz!PBle5H%0YWZpB9jH*Odrisc(JMjdG!_A(xP}gll=x-X>cra6WM%Nz> z=7E^_w~sSAD)|fU;D(Pot4d>Zl$iQ=|69q|6tWXvSO(+On>B<84gnUbBsjkoV0RjT zp#%HV<;9l1pIr*HM3*TD1bLYT-XXpqG>y%Mm1_Ae8VrpUZ!}iX0{WyD!pfxn%G&{Q zxoj!Cs(2JpG}&XoIg!Yk(NkO&NOSfzXr%5+djIFN*b=Bh=yX5xfHz>%X%lZAL?!@B zUdvqCI?hrv`~T0*E=EFPy!eWtg^^ZvJb%*LF1L?RQby6=QRUzCNoXSC@u+j8W^@+v zIzkaidtg%?K96bPlB*CMt!)q)%R+|g&NNV{XJeNK>-2eh9Nd+Tw-3JQMQmArtj)r& z_CLyydp3moS(ZO1j(aMjd6)Q6e|mR%%q-7D6+=+{*Ji+W0K#k+)USlF+HakFy9ePNE;?mYDQ!}>wWMo|LR(w%d zKvcu__&$4i;YRO5q6RKWm|2+g(-1y7f%~pi_&6k_;4f9PnDq=&?Ie>R>9;kN`5mm4 zASsQEpL4&|N38oN*&kXHvc43c&#VAH|8yntxg`zO6KIP)w@RpzKB zujCr+p3I)%@-?l*Qs#%82c<_c-w6#WHd5SOU`1NGM7kTi6fWCc5v+y^u4gI`_@ndR zc*UJ{8p$d)qNN7C=biL;-DJaI$d|=ZRHfgm(tIeUbx8AKIVkdaw%GlFz)|-T15{u_bqIc}Gj2F2LWk?qD58^23eR#ane! z!5I7|d~?8)?InMko3Lm0-o4^7XZ5?E$uL2+cE>O(78VX=Yt;c*-{1>yvwmHr3GSaT z4f<4!g9W=DOt79pb}yF{bBXYbgFCKOm{tz3!^!^nJa0XE$TJSiWpk}TfYKl-Xe|u4 z8nMx5ADW?y2v0R6yiahl(97}`j%GIg(fuJf0z)aqWzKk^qA6%J+>z95rCaFETc2E0 z=f5T!5Bowm;tx8iB`laIY)YqwQmbZPEMg_07=UA*GZGHVDl`I)tU;Sw6g3;uT(48{ z0X-+eXc9=^-@#%YBrO#2pV%Rs+pAvzt_-LGo{lny^p-qXKqnvmOrCp(LsG zdN|Eb=8pl%6il1Gk_i+kAVK29k2oa6O3v9A`ITIiM+aPD^0L(y5eebop z#(dTF2Os!=p>qw*WAAFK0fusNAViJNha6vneDGTw5utERRiuL;U<1R_e~+O+$wUUe zWgk??)X~DaM*2ttX-W9BZs*Y4O)Mg?z_cyYtaEL&Z0jrdGw@5NCUzD^X5l8WoYZjJxRlA@|{Z|)ra z39dmR!Nn|BO`L#Ei&9%Lorj z=Fmmm*|7DwYDtTjmc=Aj!FA!ePZq|vAJHnSLUJ+<4SK7tR}luLebcmDtxKe(U{sJj`LSj2b3cw<>3!-|k{8TG3V_~@%o)$;BnP=p9#S|2$u?SGcz(!4q;ej*<= zK*A=tM|FpxUMW+fvle0kHqa`;&cq3w;6NSWFS3uBIHU{`b+Y*LiI4;Y--7B5RF@mLhQgrw zG={^wY<#N|MMB&MR?C*J4-2QW?M0OslwG9SH`;QM7kUWH!TXYAt z&VLwIPZU!d27trSBN!hlh+P)7x6Pp`gRJq*PXDIF8JQJk8M%*46*+C|A)P(3@0JNO zS(RR%dp0OLAU4D zM8;D^*VNn=sE>(oX~y2+BX-ptBeN!bXR4Mw zmk0FSgku$~E`4_1%&l{QtRsAMN-K0LSV35i^$l0l1iu^Y zx{sVE+MuDnJOGQr%*a2hF*)oa2l2?W(4sAO#AOGh^Hu-eKNj2zqJzJu|62rlm$F z3nwa=E@RJSqp0L_JX1zeOmO=4wKL=KdYQJj}OM3V^}2qI~N6HcKs zhrTTo4!qbkt%?nA-oaaid1A3=-~}BnKwiE{mkwoBYwc&x=d5#!@@mDVg}QYVo$l8X zXq#zzAn6nLMXL%uc*34bFkS$Z`BB5-0&hqQau3C0B6ojaLSoy!{h` z8{TEn%u!{WAVX39g63)^AuXSg(;;A>HUZ3*O|AOq!n78f%p$^xYCUhs=)|h-mfC=q zNNy|G#B{x#==tqxBW#+L1OKSvryt$U<6L?fJqb7$*rDVeaAnk~45)4yP9*>!(Y&+q z3>r5LDYzC55-~P(d1J)6q>(Yw^2tv;HDTk-e5&5N4aEP{HXDI8fhr_Hx`@MIBsqCUsHw#!=rT~Ymf)BpW~Yxh#%qoYL;HZBUtP*HHQl-&<$k<*)d3x5 zE^(z&$ygAKe#@CPF(DtPS@^Y@Q)OLBVO~kMB<^FZ$z%D`4~}>Ze7!zqd$i@RkfVPB z!T8>7gO`00IbDoJvsfH|^@*cSD6qyb65wAiH=9Y zTU4V<17s5IRQWh66;+Hty8MdiqYXfXD_Y zASo`=m>6(QqY=EtJ^+!wL&Cw41D9M#$Jo~lL~GG#^-jx+$nXA0{D~_pxnhj0V_kC_ z{x%|7AU_RlSTy?n(tAjZ1$%-a=rB1;Y#cHfaif(5#fdSBW*;mi67%Iu+n|!%9hAAr zttpDb{u_2I2{kx)_a+xJi#E82w@YN@sAJZ@zC)lFCFNWH)FbJo4hS?$zg zTn+GQu|H^UePi<5H$?%m40`#+zQ?~^)ExlQC;aj~{lC7Z+6Uu|B<SFtCeq;GGw6sZ0_k$s2gSuyM}uR|W< zTGa9YJzu1;NYXwhq`%04DgCUeoQh9CTR?){;<=spxo5HJDiVmW{Sj)mxUOUa;%3kFXTk+J!C0|bIW0j^ z+?v4i-02%$W}I7GEppE8eSR4_Dmq(k-EEpTvEn{c*`^3JrXZ`MqmMGZZb_(}&Ctr5 zdIZG1-K!4$cXS)Mlsf~WY_?if`RcBB(~m%B5~WX2;g|c!Ud3vGI+NSXwC4C0+J~pb6D!&dbmzg+`Bq%w1jaeB^iq{D6QUv)?}G3 za(oSUg@UK#WH%+BOh&a>$eDVBbpDTTk<7pYud=zjr*k|u>mK)*rHmqoLH#F)WV2ET z&k^Tz)l?&VpJ33j{n|j(9IiTvdH3cUR2s^AoPb1_EINS3<;rr%w|J_--Z<1(9+ewV z(>xEE84d<7hd2X4a75+P>OAdFl?U!McFF=4)+^)3*G`3}HVJO4FM$wPit#AOHvUDu z;?r_VSNNwMet&2N%9PRhttq64q0%Bp8w-|}?zqalCW5WxBq~ju8?a`5I1%YJ!R5(# zM%25?z7NL*gCp7s7=U2EZ?vT2u{%BU70-`u^rZfDB#6bgqKo|ENO)7*s1M{@=S%qg zcmJVXb2h^{*fP#=A@_rl4?+T|sRlOOY!13$*nRaX9H{OlppHKvx>16oRMKVdWO@1G zIZ?DBuH80iH`+j?g;bTZSZh7!Eb}tru{^K)h7)$5+{LxCF7*+dZ-x zSIs*0yxCH?B>fWNu$m}_sldCSz_C(5&y8G4Y-?qROe#29F;Aguq9Y=ab+-4Dr>hD+ z3UNO|><-=P012TonyM_3z+PRz@D7bTS5GhS;m@#p9HUY>`CrgG11mYTYEs=dNit3) zR>3yHTrt!HC1RGCF)2tDcBjY`f?QcPD3UUMV-hazqh46bU|iM)n&H=-H3@H9pi`!- zSIJAw`CvrtDHw1X^nW#2mp?Vt%D?lrQsVK@P~GK`%juLcdITfe$)dNJw|7Va zPAJ@n-dv)3{+pC>$&U&iiITe_MMYv1g3f@kbfV9nx#D{X?qF=0v)`vXzWY%?^!E`e zmR01PBWkA-3ciPD|63FW0!_Zj&W1A0j$I~jXMLbBV^+PHRH&ziY1p91sDdf<{k1mH zaZ5@Qfq}aa)t~KPIWVcNYF>D<(aFZ*z8uDsco81%Y>nJ zP&))mttZ|enea<1rsJu)J;nu+&onH-d1=X8KP?U?I?p(9Mec{e!b4#9Z-b5=O=TpZ z-U+o#m$Lv)G}{+|9?Gi|B5YA{@m@-J>V+={zi25prweT0jYMa6A9I8b6JI%vjIwq8 za!|Z%C&rG)0~xju(GxY&E<$T5Hr<@NVQ|ai9Se2v0TWukV?7tiRvcJuePWJ#%(oWV zvPzsPEL}yVF|fvS>v-?Z3TkT77(dO`LEsa6YQG)wJqQ`(iMzlimgLWiQ<(c$YWQD< zgQGA0-b>z!(ue@75-9wu$evPz45{h7SKb(bySlybtq|E-wfr(~X19A>NOupz@lJV7 zmqbm!$x@j8DC-nI7gF5x>n^l_bzpKLo#EdKw?)68d}Xz%1xo?!8<&FV0S!eDpDw7* z2BzhAdPPFw?WdV!95dbyp=i6uC$8UNr|*NCB;snRoh!D*mVv%rFz11^SEp3uzhS>+jN*r(fGGGD@$4fHd#6 zir$VOFTkLW$f=G~X4lT9=`^Q#BM=rv4WeIa>j#gkIb8VvBuL z26>P<=kBUwtn~gnY7Y6QlkqOTv9b)si(*yZpK$!doixu7=av$YN!tfV?X_g=d}SAn zB`0)P&3!rugK;t)bRHPqk)Qs$TRLP`4-5eQO80v&U&?&LCmJB-?h!UULiR$zLXWE6 zGEq4m2rc=bkll8(fE@KGV*-jL-ln=2oZMF#)F1U~R$@)dW#2I8r4z_$zQFQ@y! zBNTDsG$@x#%glb@3c(Xou-r={&@^spxG4hbqfPl8L1M&FW8r>M%zC4i3^-T}Du(Y_ z^G@1!ex+ZYfR>~n)oF63v-s2f7e)a_4jzqR{VcxFEp9YWfzSG4g=;fSNd6?YeV~}^ zk-#;vaKJvI(<%z;wf^!-``p*#d8&GClr{AkDa`WdacV^*7a)O@x&TE0YzUp;G+Ofp zfjm_Y92-HfX$y0K8Di3LzUR}!(y=Wjt;uVx)85yM&7POaU=9A5#G)06e>Eixgm~%I zpxK7qROsVqGzkm_7TlN(gfJ+8?pY$M=*nXQ=#2f$S~g*JDFj6KhMkC{qM^x;INy?P z*c0K!_h4*wM`H71nMDz-7aFDxT25?oI?iNg1v6W21UR~ZgDvx}9=NTVhi^`EYHIw{VgzJ~8M@BYi~ObDJ~4reZ$6fQ$5Gi*5$(U8z>oH%92+Fet)ls-iBS(F|s_21{e^cu%iXM|_ z)w>91Tn19XVyy3Si!Chca8KY@Z zDs4j&<;1=BPP%HEu4A@1Z(FJL8RZ`1JU(thP3eXof)B^?L^~k=2~PY??&AJQ8DUhb z!w4P)T}bl&yill1RYp_X6(4|QP!lYYtlKCgNka;6E!!gYiV1?NYBh@5fwV6UEp)er z^uk-_sNon;^}*m>ExT1nLgHH3fLVaMwOeyvBm)QVyVuhTKp&4RWG4w1Du(aaE;wxV zDr3(x0U(~)@-R(G_{-L>X>Fv{=sFI;rJ-Oc?M2Zs839|SUIhSvZs#G|QQ}gTt-1L_% zCs{8o$kFY_@TAAiTMoJcU#F*BGQ+4m_g)UTubJ*U0NQcu7p9q8=H*sy7qSqGe)7%; z=(^sxF`4t4N^lEME7W2P%D(r&&5kfU4_dS+*jUJ)Luty?3G@>V% z#w&|ck6?;c}rvpN>$=AQgPkaIPJf7p@_|Q z_00M-Sp3G?FTb;G;}7oNq{jS*fd&d40%$`*3S*Q*+VWTdMG(q?O6hyfnUFz=IG(Ai z(`GgwU(pYog>hBV@N6;BF)|LR!kt3<`{zP3FS~UB1to(S*|`9$ZcXWs9+)cGT&cQu zFtdJCRF4;w%5vNfdXXS@;(*OeeQe_N1#o@u3z|E3S5*ud<|kQrbh2|?dxLeNWQ(E|j=`rQWjnUjtsS-NcL2HbD8OmeF5e3O>{%4v| ztz(aQP0sqE=?N0RxTSz|%x`r=RG&=?aX%JW(!kh7dO;a(e2hR{K8(RP)8NRPXZrHah0U&9E! zIiWSwAp3)6pCD4N&>er3X1U4luj_VDR80+?{HvJUysu^j2%nZ}2=x)*zgE*Q3!)Pc z7IgM{Q5)QM6CkHok5bgjEa?r9U`!@}3%>)o?rX9#>kyKa9SGl__GIdvU00chOxsn< z6L!I2K?`f#?@Kx@$XJ;j1(_#i zHyK>qj7^P7!IR4tr5o%y=9#q}9Hr_g|M zJEP$nFQuBAYG%S+Gt{sUgKnM>8ef?o8n2*oMiG-*;=r(@_I>@x#5vM=$2h-o9vkxX zY2x-gSC6_4eet@r?!qXWNil^wR9b$SqB|)@(r_Y77wbZ?MHp)-`B+vpifj@`?Vb;b zc}q@hv!ty6JlcB`%#f)N4QWXN(=?JQq??i)io=xhYRE^u)43P47G;7tRY*sp2;eO4 z``*Z9n8K|^&)X@JpOuCj^gZZf5Bb(2+iOiR`^UCtyBvbu^}33tWnq)}}Fd69<^ zHrCIEs#XO)tP@b~X8(@Sg%s-~Q?QAIj^(-9{nr(VJL2N(Sn8_lviVh3HM`ss^;4Jr zS0{`^v>_ItNd@1J%jA@5?R;q;-&|J@jDQ67y~@r2cuP+ zvTU!>LWjM#Kh4zF8iRT*5D#h(Z4XL5q_ANbI9c=zv>}vwGn$?zGGw7N#L4~CwEz=g z*q}Hc%0$w2MU6PLKd2xUvt4g|dOtC$X17vqU+_S&S{KOX-g4yiP9cRmuyLd0Tf@NB zJFPUuU&%n=rDPzOcp%PR>iZ*Vc^H&`n{U0+y93i0%-qr*b5n?v&YyB-d^@lxpoK$w z#bOwHM)f+k-J|Mui?^G!6hha3sNlH5qJ84Xz^Z7cLn1KVNMfon^V+~Mz8)Uu;8z{7 zh^2Q_Ucb{-I4#E#8)F32yij$wb@}1wU2%_aw1BW-l!N=<3G3bb*^P<I$GwxVj)qm5bKW+kM zyn=FFjnJ`ua;-T{dQS>#vemKwF5-?@}Zo+{z9} zVYeCDEm*43K-VTLmfMp{)LQzL>-d8|e+eXL2)2Ul-IHa-H_>`jWduZ`LF1TW>kn)g zY&)zoZzW@VL#^RUMvQkj!R{Xv4Nzkaq1knV&WyFQc;@PMtv<3`vq!dAyO=zlISOC;XWOYZ(yRIv^$d9Gh_oz??>s>?N`Q1NqS`RAOSExoT~sf&*t4A7yZi_muizE= z2{;qFs{Fn2$%5k^xbQN?U4>IVjwl+ub}O9mhZ-aV?KOEUvZ(t}&6`4LUVp{j!oAO+ zIWs;GJzO54S#NpA0pDs&HzxCYL~EZWYBO_$#F`G|F*qjQ|Nb}7i7qV%LUjJ2eB~yI zFC2L{?^uLRibv@9;65s%e~^^I;U#TM)38{7r&6|+MOY=DmLXCL5sP}KHTw&-ZHJf& z^YDdnq}so=uT0$M;ZRSuSb#ritH$`*o+|V~oy6Hp zJGJhcTHn1t#2T65NaEll!0f?^iqtsEEBW8Hwf_G3I@jQYm3}avoY{*3Xd1sYGy=1xcwQqF^q1E351a_cXE2*bmS^_lO+Q!TdRAj!b|uI zqG>S?+6d#tk4+we%Kj*bCttI%Wu2HTsuAZWNPInkZsCLJbGI z+Gfev{%oG{FV|r%NP2blNset( zx9iZDf@;4K=Dg7EgsO3P9q%2fv(@r-#zto?toR1CYR}e>*QoGDg~G^E)A|@gi`wC$ znO4{=aZ0)W9$`C46llRx!^&Ykx6#c3V}`I;%!x!;D^2X4ZW{&?5wVaN3BrH7fT1Iq zqAa)~Ky)Qb^cs9!0t=QdCH0WPN5@&s{5|p;`o0aHQv!QBBSM!7_Mi;3Tc;AW7!*^t zqFwW~6AAlB?GZz+F!DQ@$%)QvGZ};8Au7yg5gRy>ZCIU6`W}dg@V^>y;RgYMn5h1X z*{KR|_wzLghBg?RsKLHFZR+{_K3$ z_zQ-n7D>%r^Z=fi++WWJlahGdDYpsRg<|Nq7;|J9w^$9_qZF5jFkz}^h;QBilhs;Y zmavA|mJ~ELqL{eHQ#n_PYVi|u>+auon~OFS&UepsUAy$7gt@+q>b;LslfT>mylcXz zOyd9L#jo!dCog+Tjm3jEv_piXrIg4ZElwV{T+rtxntIfpaEGq23;bckLZ@V!_A9+J z`rUmQmcg-9uqq*QiYAiJTC9Q4v7 z#kTw8?y}I0&67^J8BYvRX}p$y*e26sw4q^BYn4FzW|$|HwRivBMHeBJLAJzKwMRL) zsjUwCLH6<^>8${Y-RS`=F(jkc$z{s84opRO06GnyuPaCvU44p#;j#P%g)k-v`0x>A zlT<7wAP}vkDenU?Eq?)@&&{*d8k@fgfNzk0W2_}YIfuT0lgS==^nOOr?})539rs0f*Zrhz^Kxg=u+|7ep_&r5)=$Pj)$6!i@1yy_4Mv3MmzVnu^DHr} zIbI`@=#sfk20fd>O_lUDO&+aG_`hw;&Hv{5xl&&Re7+tjTWi+5$@t^z7NK?vV6Mt_ zZa(U!+FC345{vUMR2nr{G2(UUP1dV>Qb42IM1jg`YB9szxZ12F(;P@AqgcWQAdN)b zC7n?W)FLZuR5^yYN|uhY1kI(zyV}yHz{t9L@sSC%8m`Zr2RO#69{lyznD!Aqqx4~k zC%j{3=ZN(A6#L#~FfB6xJ*nLYFC~5UujbDK`u#rr*1{0rM6*t!noz(hG7(XP27<=S zQmIwr2WRjH=G>4W^b!9L=D)>ENyW_ZgqB|@VWnSi=D1yTj0@P>w(9q=-Xt+he^a40*Q{%`qZahN$R}mBLU+Trz0YKzM%6`@=;D3bxZW`PTr@5vbL?AQGBQh zdzk_?`WocxOBbZU6rwa}&cdP1TlKMHZE z>6H@u^aJP}s=bO{)!RaZ9pY_Q=$D*5Fy~B z|5{&?VufIQp$D>RB4QCP$o_4CR7HlaUS`0|^0Pt%DV=qTEO~->%4EnCXZ)v&tY*7W zZ10O^SI<>yuqXu|`>^L%C^vx*j~6u#8CtZ(I6 zIm?YA8D71AbVJe$Rkh6@5zMD9AlVm;+K=@6CXev9A4g4A?SPYc5Am>4a4sSS6Lt&c&r!02$Lv3~G_%JOpv_b%?TQ=! zX}6TJv)S}=Fvztv92irDYgnWdIiyq;we{88_^?b*2{CM}u#@vIcrF@g9HxKdgSmfC zm(5HpbeWJ>Lk7~mvW7jL5hm;PI^9)r6#4g;dNdDQ*0Ij#X~N>53Id6~FHW>(M_VJ8 zbO8zqUN^EfWN>iFxT1;x>dSD>UTT;_ysAbW2NOy#S8+{J303O$QmQgZjFYPHbxQQf zgAseu9B(#_JxjST+n29Hqo9FwzL7g?X9GOz+lPn+c{LB6sfb~L18CToj|K^HqNjO~+XB~OJN!SHWe+NAQxs;^+(mBfS7l|4RQR`I?si}C78|-!| zY+msEp|g&LUw=ZVoR?%PLLx&K|0g#m6nwDtA0Xd5#)7A5GHaNHx9Lr!k}-XiLVDTi zAxvi|*0l**8y{X1#8KtzCn*R3qdpu#)mD84OSBc|&9j+rvb}|$4ok?$SRlqO{C-!m z9vok@Iw1E9LH*iK5yi0J)Zo5n6tach6}b6)cY~~~#~ER3611B+cSJ{QQEI+piKuinKP3v<1JYxD2wrPLzttcswIONjd)?sOnv5Rgh z0XC07dgX|SNjlCJQMjoW5Lh->J{Q&-u_W7`lG?WoWQrs+w-M%=R|-50UOB1vBu6Y7 zb?sP5QWr-4D)Y@5*UI8*$zP<{-D6q=^qH_3c%4g_7#Qv#7}oB zWO(H-+mj)mY*(3hL6)!zl8trb;34E| zL>~l5$eKB-MymuOHLRqc_033`h{Er#nq@QlI7WNla@w`mX(+tl1bd!xaEuWiKG)Xx zE}1Azj_`O4a=gFtX*gGO9u;CQ<8tEEZnxTplk$~rgui^`tUW!&NlRKdu~Jpmxd@=v zm57ZAaoKl6J8bB*KiAnRk0a(J28w?J?+Rn6Q}&{hzRH!Y@&3NSEde55VcyXs3Ju=}PmUCB za8T(Idb7w&+muKwrJ$8ge3@%XEYIIa^;Edl>+Y3n<)Wcr!i-{7{aLBY3;NVlva%B` zMc5~OK&!Iy{-5N1PywM`twGJEg8NK4<~JL@?+~0m2&j2zVK)*pgI3Jjuq0zy8f39flU z;f5@XCjGPkz@QPdOBwMZ`Qp71wdY^fXcJ3`;-_=#T#k39b`xg{tAHYwqnAGHBI)aE zIuW+;!sw9FiFZNz3pnP~BgmkVo4kWk2ndvbE=Y`(3qN(x_1 zA44Q0P}9`qGg#5Ro3DXYAJVTBU3%_@i`X(J3Y;Q6-K>a*i4 zST8k!F85(QkPu&fbzO-bIw~cFsY9Z!u*L%wcYbeg*23FI)n z1+FGikyGgIQ3m4JO~#Cvt#7%oi@Ho2-8$-kS;(_z5R(L`PsC|{X%~K$Fk5sphul=x zR`Jt|MLqWEMqXgMalE9`XsCC)Gv&M&y0N=pBe>7~C|!pZ1?eA&R`1V@O)%AMDgDTRwqAq zq@1W~Cf$1yJ}e>Jq*}Sjbi|8z@A0S48vrva-a}^i6pnsNvCvm#=I&ZDK$(6$R@yh; zywM{4FhSpV>UM|0I`^_{z2Di38U>?xn3?PA&f~satFFce(E~GT`IgJ*?}HxP^#Z5N zYEv6p`)HVw|7jWFYE={~SFfrsv6nr=XI}bwJUZaN@;tkb{!oE}f=nPFO1-6Z8^?=C zFNDad2CnVkNuhrAilq{ANUh`q5Zki2*Qcfg1<-N~u^8kz3$_D*eBut)QX#xd7N*&V z03{j}j;yB~@7+%p&TVFSY;Mx)i+>YH9H+c$AVZF?>`2PtC}$wwHdp(&Wclb%dqrb5xsXw61-}vHr;rx7%U&K=23!Gi z@r5}s#R)@0N)vdgmG9o7)_L3oRBC9_!jAxtmx2|s5g9k=3ZhwS-~45-zsdw1wz))% zH$G+_K2co~)tiiFzWpBBvI^IDkB)E{U+>mI={Pdz7O?olY3towalqMf4%JG^_M=U}rCfIGh`%sKb@dNCKfFmv-DY2b z^r)g5FVAaBGT8r^y!-a8h8Dl0{@xo~G!T8lS2PRCi{NbfMiV$2-qM*~)bgTPS_@Z5Xk`l}+mvLkr(}IX#mput#f&~< zvZ#7y^@fM)*I{tz{pg@sC`tKqtj+RPvJd*G292{KYn%QYGU73)qEIvMvHi2`)+i7^ zY~YAZQVdE@;*n^)ie7*5Z~kmUNod8j!CUi#t173YhXNL*APk&iOR7e8g{lZ*#o zPOVb=Jj4lMmHA=6emRg{l!g;`28}YFsj8Z1R4bWu-r?^^I{6U=N)~u&pfJ`~_=|qo z$#zE8$hQApb^-mhr7~|0#AV$YmsCO0lFsi9+Hrl6CmW-9OTL%v$oGI4_#X$k7~AKZ zI`LhStftFq81pyw(}b~qGZByg?w$aWC$c&oAG@;YtLd&sW04TzRc>UG|8_~(ZS9b$ zo4%;qA1})(l6TuT;{5nKt}H-e5dbFN#Zl2G;P^Qyb0_9US2c=_)B9L+#)_;DpX$ujFjXDucvv%R_1 zBUFubFXy)DRKptzRm&CgqN6Uo+3dadFRd~!q7Z2SjHDvhk~rnlgU}_KjWUBLXa`Y6 z6T^dcX#Wv6d_KS-pROY-bK%JIq(|1vQhL>Bv{Tq|qLZdVa^22`jnTK;US$gp596}l z6@W@_3SlL2y35SAos$GcQO^_gCalH2Ys)I(2yp7Le3e1P3a?mvVXe#yC*|Y-J3zlZ zJn_~1XM1C!>_N!IZ^YDs9|me2IXYrq)`fS=wbPTXib1YNQGECCl70NcuOJUFDK1PJ zA7;F{zV~Vny|(xu;+QFv(1teXKnbl)746p>=5~Py^B;)K0dUd|-2YR_7(aK|7ROhk zvRw&Bni?>B89$^5fWLIQYvwuo(W+BD_(ulnf!2b!iEHneq=6`0KSH4_B86v;P6V9O znk>8(Q*X)bCq}I!_ns(C&p-Nz^YQZVL~EL5`$o6Td1=qGyIsU67$!4ZM$+T~TsLTX zk^_r!MqRYuU1EZ7jIm>8Ap57HUM@AkXYt#K>+z1TbPRMLu-urLx^+kmCrgaE_c8IKqpz%=K^so5><_Rq}Ay9Iw? zxi)A;+jl##zjA@`Y7-vBlj2sr8CievGPU}Snn5fd^9&AFX$SXme(VY)W}1}q=9=Po zaSyVC{&GXA(6XiLL7k@nHeuHK7KWntBd`@e%RQ&uiT+Z!lAps6VE-3JpHX*w zo?DQ0Ji*TFFF`%`P+Mh_>VLng&l(_$y2MX~63>0aTi}sZ=w^6T0 zV$tnwJX18QXr#<#=QNse3G5KeDfrkm4;{7eTs%|Zz?JDT^>~T;ac}H8?k#^#O%w=K z%I3Vt07qQ<7r+NHaVfW;?L{mmy)7QZxd|eV znWq1hS;ZDt5ar#ebnsb@5~d&-)L$Jz$7Q@1BL4XpkmD2cW3gVxvo$V!cQWtB~i;Yg9kLA@!gf5q#=i zhl~s#qS)g+O-FCxV!L{H3?H(DYJ9Rp;L(U62fjlH_AHk{LEskonXAaC>Ck(!-=_wR znEtAdnB*oBJ$evgB&g>Ur>gn@i)L9XH#I;`zkmP{^%Eqbez2(sOsVzn$TVV=Dh-A&5X+t3yq`iU_f8-qq*W%p48>n zh`Tzm1U#mJ3#KR5==g-}DS>UE#A0DwD*hLVQuBCigW^M1eYUUJjKK$8^e0p+W%=c@ zWXUncHB+wZ1uPM#WSi(GLoLx;k)%`3CFI$YKKeR?^V%kprBzw0kkHrG2c{R*?X-J@ zRxt(oiRmtZz$a|96kLk$Zv538j|x?=^APh_H30>C)(J6^&x$ipB%w?+*+DAhL6vru zeO7)kDi-=Wr_~SLjW?MM`<@njVtdWd@AX&_#o5gYSb1=vkcG6!BFqED?sWdTb@#mA z5pAY+*p`A?Gn%zpz*LajbRGlfm*N(`20FTfTbW{!X;azePGZ-2A?u_}p?;etaVN2} zoU3FViio(*u25a%Idp|4%;CtEnl@1@g&n0DlE(i@ei)=OBl9+vSFWv-W}?4V6aw}a zeomijP^C;TFGH*8+h9v>$;q|6D1r2g3(*EF(yhe#BE37jtoz+a@adgY? z|6_?-i8kKp^LAg_%UPmA(Hj22@AHNCh!JTz#lU|19&3*y-tgCBIc2 zm5p*pqt;s@dcn8ZzD1FT&Oi;LQs#7qJuEQ2D-LuvR?#n$0Zqmd)g-j$p{o4P3ZhFj zq*pxJ90U3=qkhSoMrz7_Jl!_qQr2N0v)WG)#fExM>hO!2=ex17bY(3unW2~vQ#r;EaE4vFR^0(|fZpKM*4O5MqknRoO-4&BB z%1`5@F_K%oAHl-5ZAlh*JP|dns^>Tw_PVGw^_kTCj&$H|Ze-NF;U)_&%V4h2m3o%i z$g${%>>CSg)~Rj9ki@jQPyLP&!1D0IYp!wF_9&61ly}Yr;1mB_T21qiMBWn|&?+9~ zBoFjxrOPSqWYLjeshdg>Bq*$(#@4WlHPRLnD4nf9sw(N^5>dMui2ClcR9WdOqQ_iq zh{G9$Asm9ZG@Pt{u%^ow_p=2jCmpG)9&?6Fq44>1cp+$UlHQhi=2hW`xEv1dZNuB% z4!8~`Ln2vve1JKu7|t!uiopuhopgABBmDB&C^_+y(7)~yeGwy`cl5p}N$XS#f$+A% zP^usy?5tjsQg zIP?X}vM+9-yi!}0QtI@1uV!xo4i(>lrWJnF*pbsh9N)o2VwhWT*8!!<$bmL}_+Y~+~JX6i4HS~>xuiCKu&dR9pooad`YEzq8mF$X?ebBd8x zoe^tBp-Bo*d8Xx#RGCy7yB-4gV}O5#i5_zk-sqT9vP}(XtO@9NWavBeEoSLPxi+tl zMSGvWn+w-IP>TVrHgF)flJjYx|HC`si!$I&ISrAfKyvQ)P$OhqCF-BaOn^_ z`rJ6x4X~7?1MT85ff6-)dC$Z>NOfvW^!++QD<%SLU_r^`42c*53P)wKWXWu+zoGUz zHxPG*0)NCfW@D!i%{W>sSIU^K*m5NgXGt#aJlZD1i5czvmE}(9(^nM2rmczdpm)#W znH&m%l$T3MgxaMlQziU@!VJu%kLp!1>Vt^2J$;s#)j*=oH00IxrPp@-|vR{aQ&JYC{VGW&Qa{?*-AB0+vid#iZ|uPZY?zQ zUv}+I!n@Q*-@9Jj`0g1MRue{~!6AomVCU0euZrUb0x4w39gc_#i~`njbSS2D=6{~M z&E$4YJUYmhoKDif8x}$08t?oG562z9>Lcex!9PJylnr8NlSqlZyX8cmGJQ7AqxMQ< zLP8N&t+qd;8I?eqr?eE{#5=1fr9^&!S7*AfdUXz?FeSlR}-pIRy$?#^5rZipogX4U{c2g;0~x&aZM zqDM{o&=O)`17r+E)VboasCJEs+Xz>}D7TxXH$a|`VDYhxk(nerB^@u)rk2qMuI7`> z)r0Yqij9#6B0fQKe*1qg^CusE(^l}`#k`pv*`koPLJgdfQF1Lrc+%GY{yVrtihl`~ zvZ?J(oE-kQ$D~Z_Fe_M9{&NM9eGCXOnWhrvceo~OWvKC3$+uBUfh*f#zc!906=3xR zm#_;0Z}Y%~%mtRaA&bbgqn2rbx#^WGS>Dj*aC-I95-81TrLt8Y5zHRVyX(#o)VjeZ7pcQorzppj?)$!0RDH}Ao0CIC%X$*qy zr+V09qXuiaY-Td6xB&Sefml!!9Ob&Tj%+}l3;JKQUM1Xs#8aKDIYglia+w=t3Vo3& z<-&1xv#G?vmeS6w@f^yjZE{SI(FZFeIECsBdgU47X?*{Z(i_DZ;-8^~9Ebef);eH_ z29u{pJrfxdCy8QO-+g`5Y>oheSs|?I2m5A6MYO9?^lQQO zYWV_IQf5r*F1Y)df54H_MyUm|+JHK^0hLS8m=5=FaNP21flzrT^*E)8YSy3SSxtW= zpKb`lJ+KSkJy?-~Eu(-w`=&WQ-PR%zO&PVu&MM-lG}UrK9V{;Rs10HO(Dw5lE`=Am zmn!KO!R4)*1;ZSS=4?@~-mWq4mJwK|?TemD>-{(t7|Uszy|HR*YIX3b80g!Y3uc*C zDx1vj5-;+qeAm3e`*cS}TciS=@))#=dj|JJZD#|~-aGlg_+h1r`_GY#sohD0K>&OJG*#h;e z?dPkxdETcJBIsnd2Ds7*8+UA?-2%|WC%hV`SJEZaG{ZmtNXJOHab)nhMOWT|*PaSu z_(J`>z?c@x8u?twAWkmFz^Tg4f+7)0?k#sC8UZc zI^r2g4T!?wfG)t0zdJvwpp(lOQ&K!{I!f?HjQtl6m0|Sh_(sfHwb1z(PrwwKJW6&E zOTm01#~(bZKaV$dDt86|>c)ishsc$;7&Sge;k|G7yPr@NF4qTbj)H+Onziuy>h1m3 z@LL2IEQTq^kD^6&gqS`<3$;ZNzGL@LN2EEmaAXvAyw51~Do7^y0^5op;IE?0Pp<9u z{Oe!q7{87~)zgUjC0B+ZOnW%ljxQFtM>KOVOJ102!F>!SEOH_daX`2cUY~J;k!i0_9QHz#&75$nIZY*Nd}^(KNpG$IV5omITMO^^aPtBI1Ln;VE#@m` z*t+~_R(56pvit6$QviMAPBY~7=Rp{RZtJMa0Zy~P#Bj>&UgGZ2?Ma~6-r z)DMD*kJlVa!i(OxRNFj{^=ixZa^ST@v)iw~umsWTh{OnCwDPK}jUsh10Ee#D$a11Emy1a+pG@IVA8l7PVafzalNgTCc|Mkf^YHaz1 zAUS6?fqCF{iYh(b*3}W&Ahs}amDWZ)?`V_Pj8kznS-+@P7zd}o+wu_GVg6Z)Y^AUK#Z^0E46AtJPXNPj+ zEXkcU&GX4Kw%I=J7ZQM>C4o3=;W9<*1z>q7BL_=(|K>O8sS}X-m7)lI7cCGwGc>if zH5rdmC~6V1^IwsWTOA?o8t$SGEk$ZSlP_TJp%J3fm0?yaXjnk6rZ&opyfYbS4X`5# zoYlt}B&QV@oZ2LO{`H)I`%l+&NhAb6rsYwosg2)q3h`HFl*>Z!+OIuAQr_6;%JQvF zAaiOffT)Ne<4w~XlUBGWpIX5=X`SxSG)F1D2D6Q)OS=`yiQ-d?)dqA+*yJzf412-@ z7zl(4OPt4?w5sIekgSx&UpvG__(4m)B)J=ggEppyx72uEOpC;YeKKw_SqVVUifp;DM>%vi*@g6XmN3t|I22Tas;*(Dr zAfQV*OvFBGRX-OfVUqqFj$>ot)~90KsB{NOFC=is&Kg$`RctzCp-HXmh|A>X_Oq94 zBRonImz{A$RP(>uj``O;8YSmAl`aUbxVtTcU;xVUfl_PPbj-?R62=7ge?VUKY9r}X zZo0yZuO_><=ZuiU%QV%dt1lmTJy7kXjmL*sK|-k!ZP#=U;ugxfIu=aaz6&?V@(}ri zv6-s;u41L2fHgSK;BB9xiPQ0{$XRn?F(c#la?QJO5LpEUbAm7K{!mb)@<8if8v~IfUO^6xK=1GMnwCKl2PG6Bm(w` z$>#_uCN=9snRT(k>G9qddc)2?xqo;yB`{fuY)u3cx0EyN;n$%z)avLO_n~ni1jOlF z+;>WBxNb)T;gE|Nk%ubIH`)?VM z6XI>NX}6h)3nCkBG3!~%y9s-|w*7$aRfo~{6^=4f5-oDb?H1dzXv* z%%Ayn&-}H3%qRL~5@MZhC6TY8K5>9F3OABhV%E-^eWbP=SS!iVW8cIm-TixSJiIOx z@^7)p=p$G%Kbtn6k1VlqSK?nY5(u&fKQDeMoOd*YCDfA*!AbR0Kbw6_5ibvqtV$NF zWi>QY0|q8E?=q|%&#)YCZ>?TTGF+k(2_+ZMeCt70+Rty;{*Lie2k)wGYS3izllR4JXsfqN&8;Ya%y!t`=Yu8(CHPtgyvE|r5Ay4Wb(eONxQYg z2*BSpAN7ue)NC=Ru!Cr&hf2r!(T^1g`m^tNw(c0V9nrWxFu(^}U$O}TsZhK!@CxUX zvu4d0x5s0hry5o9i7thFdV2)Hr?bMF1iCj^&XD7^33r%pFP-@J>{kM9pck7PqUFl3 zlHfz&F1Q71!}-%iG*tGI@k7-j$>&rhDY_G3qTemB-hnM3pti*KV-y_DG>~6ap6k_j z&xaF6ALS@jkw)%PAQld?8+8N1J)GF^`rV`vw0H2h+vc|t+IhG3e^80aV}Ww{e&I(= zcZdbL%b`omk>Az8rVJ4n%Qxbl<>ZE6WZ5&Oh{y?H+|O^<6f+mg>>(PW-b*GkIcT7{ z1}Ql%F9`YG9j+~3XUr~nqVWWyX&ntYp`iqc&U%$k5mI$un1BcMG+>9=lc}=<&5G3x zb%pJS@ZID(UILx-!LO_axxyd&{5-re_Foehi>fQ~aS&#Ri2rm)Pe@M@uq&HA_)s z(Usl=cj{YM6m~KaaAOvS=1Qn~nz7B_xCxkDYOerai&0Wb75G z8xk+C0n3)ws&~oC>evqQDK`irA+TgY$Uv;Q4lp$B{~z}IQGWb9dJ3mI4QV3wf)A62 zVQ)Z1T$`0%7*cajXtvTc;Fh=*kXEPxunDo)sD158!%%=IcT9%cQ&af4HN*;U;1chh zTA9DZUYJ+Uo;d>2J}{ye79Otq9;q<=ofi0whPre+w(TQ^&fLqad^3fXEz_5sx&flJ zm2%7@Q-lwCDAcnzx!(%>gI3k3n$Cge7s72hDihlXl14{3cko|srcu%=ZwbQFw=VKq z`Tx5#jH||E3DiT!4c>_cy7YPAm%@Kf)X}0KlLy{|-CTs&{%?`zdCm{J^c#WB=0YW~ z_O|1%wes@)P{m~R?KEipb(zdak$}HF$g!f3u-B~TYq9%)S;@L81A}yxBT8*5;Q~sC z?oG7SGswwNu12{cjcEcjauEf$5{ei9$v^qJDOI5Gab8QXK0zOr7KwW0-0M1Xlt(Nu zMEA}(+ZU^Sdi85jrHz%vthE+yFr+T|TrRee<(8d!$)35N`Et%O^VG;(`&s%zfI>-T4+T$9kRDIvI$ZNlK@s1M(Qcv%>1BN_bX>tHF*2`Ig;z@4S( zcQvL`%gN*JahsyU>*EK)aU-Py-fo2DPH3!qh`W`Z%WonJ^8)i4*^RBb0MoJy+4a z_f%Nud7Zmouxi^NpK$cXh`13JjXgu}qyS@Y@dTQ*eirgQpP1ltrPBtrUqPqL0`9AaLPaj?vhg z_Z5%|0>&}{ZnDtzCAQhFI~fdu`p65AF1J_3P9mS!I#9Vm(EaUz5hIX#Jn@bAZuV5u zhS%i|QzWSP9a|P-RD-9hz-Pagud!$%5T=+SZk)j-;hMw0Uf5?h$fOo!hv_DXo_gF$ zrr^)DJ5o-D!|65X2xAT?lE$iF%Sni3O>zRgtKKnDca2#RBo%+?`K*;4Cu4pVstjW5 zJ37uluOe(9hHm)$aD|o+qurxJ=nlKjRu+Jt#nLlcEO?edp5b1-bbxQgwXwLkfPPz& z`5Bkt-gQVXdwF~KtQ94_X4rT~Ez+nESaEi$Pz%~GKAYt9kt@;y-Dgd0RaX{iAU583z{(c_fv z6IDM_*#!@y4cA5V@Xx%DDu)-ds+=M9 z10I6YN~P!LTr)`|I7NLM;=X!;85O|h79vAgym-!r^4NWEv};g;**KFy&WMW^@oj7Vau-!;KU>;5${ju zy`zGqquD}LSgsg7nic;!6*QpUEA zAz>aA%LCO@RxRpi?>F9(RO7mZA3*)*DU$K*yN9+Pu3~!doq8qI~+#kqo z{vx~};Wb!7&5p?+z~Q;l$5;j!zJgZ>$b|;-9`;tM=+*I(pI_lyNju3XqBU@ZCRWCx zvLK?*$(q{4T3|&D`1*4*=#hFkqLH`#kO9w=>X6VMJEpP0)*(=o2UjLjJW^JXi%aL@ z7n1I#Yvr={bSXac@?vtp?vxl zZT)hO`zbwZpDI1d?(FWp@17}b$u4m@SqaZE^o)BF4k@x<2$Sw{@1E5Z-K2+69`odK ztnLp!eaK}nMugU;Q3|Od=lSZ^^t+8n((p%PDE;AvX!=1Su8bFivz!Luf4t^aDsyEn zPrl6=m4z1zhrd*?sFqx;Fza%nfu6cRQK^|V;j$7c%3pvyo|L^A7$zen*ydq-6tn6f zbPg;Ar#(9HO_i47$UIVXgmNEzYRQp@`6(0=P zwY#0~fP>-4W{aRjgWdn7yG1+~vh(?lG2t_wmF6r|Kmc|e;Idyf49X=B z!^8x3V5P1JW}-xS>*6YNh0C9Glz z4{y^#0Yjx<+fC(5(f((hLvs%k_GfiMDt7;`)yVlmj)!fA@viqkeJY)WM9Fci?_%y`k7>h8LL*WXlN`!m{-8O^U>&KV9InW&o%5oE->mC zkdOfmI>dE#)sbDytA?xj)^UR-F!wA;8}CMpph$TI(&;wd0<(&E*PFx^PdQ zR`mX%Hg*19vqdhWc44J>J4eNZ?S-L5qMT8pN4)mFG!R$(bq3`1^UZT`5xu=*6I7Mn zZ^Uo5lL+j)N8DSZv!J`thH%DHCsQ#-w){k}lJ%?dfXj&SmO^?s%Vh!KLa;;sh@9{?BgPo)B&jWAK3$$~D&@(v* z%YhL8G!=rQxbtjyd=858q7S-O2;2LtRV^swV~!4w?FR6cgU_Q0rRUN$BEP z74@6%EcN!R*cr0fT%TqtfeT%vYOsNRmByboY3f9fvj*?ZeLi>;gkoaF$s#0*Y(lg%fg$~!Rvy@ zUlESJl3B_`;Ka-fu7D%n`=i?fiWYSXNGk?3es4pCWLj0;5%impXuE%RbbQvK!F|7k zOGpY`fq{;Y(dX@im&=1BX3k6<86CQDY^U|p! zJUf=p9%$(@isVNdw11;qYSHdqk{gM~->o3_BdrldVBngW9M@qwY{0otn^|jTb5;~T zHaw;4xIU67moO^0;WZ|(n z)}sV#rAv8VYF?u{5n?$rPe4j8I(z*npOGH18?}N#vbQ?S{pW*K+2fPR?j zWbS5i?2!6;_u{e3Bt)9?xx-39GQMu8>lZ|%9-Qu)A0cHxWtat?f$-1%vpQ*cwl5pd zrSI9dcp8m?rV=x?Rwt?DX7j_UaUCfauAm$Kdz$OEnCoNlc_SSHPJK37`BnVbhl){) zQ@8bur!XgcsZZ1E486)=JJ`9pdph#)S!k)#KiTJL|6b$gJRIfGuB41R)Mh;!>*PvM zYuGO7PgnvS?MxsGUTfAzWl!kTeVeI%80eO@zf3mC|7d%siF@aQ4<=DNUJzB6-j5Vk zc|Uy6Wp)$u;*YZ=!i@m4zM;;X3b&%c=mx{AB^_;rUTj{4ohYh^okgXh5wTchfo8V- z63GJE^WrPPRk8NWeb!wrFv;1S?xQ-O9~@?a=SBYUe)ej@6ud`%x3Hjb(5>bzb1URROxW%!1fl-Chil|$JWoD5NL$8bKS)t6 z%%!7ysUb?+8`$@zJo(zUT_bNZ%J|>IeLE~+x6vdp0C5uQ^ruv>PPVlz_MFsP5`|oI zJEhPCN+{K9TMQNOZ_kzkJhCkPH~K5lN{!#*H!embQ++(I+GLHhYaXWA_yR1zZj?{h zf^>naS_I(ESnFOm&-3X3%-#1wt)$WhpPnyeIc2TA97$F}?4Dn0V@E%saq@fi4(LaKzY204 zsFXL#z|rPBJ$}uk>V$&5UG?ool55{J1}g$wCy0ErlCzmVykB&C@fX+K8$}brEhl53 z@H@?JOPrJ0OLJ*E`lH{{<+<1rEb87b0`lhu)OA1i*DjCDdY4eMyc$l5^M>ylv*3J+ zC>dsvkqw3h$iB3QuAzY1{%8MNwH{~}!7`xwa?)SAShS*+-mD+o)?YxC@*$L*w!CGwe6WL?{9NY@T!yd8*fg~e%Z+n}Y)?{?iktz9g>c0V z7Cfbx2D)T4?aH_d2E|MGk=K59u;GmSA26N82Uhxa%*=Ka+JdObN*asMsEi%@Ksd~u zS$7QDX}A~S;mQ=lpB0+4019G;m8cjXtIxu?V;64NO92R9kazF!ga2Gok%_k3PT?5d z-u%1YV*M)&+thVSRoqehv_P(*6~ZP%jO2)@#EqhO4HS+nwFiI!yT;{XmYwO~qn{4W%m8@BnMzGr?3-49I@s8oq!u9)IG z^{n{FPaqs=TkWU4S+z?9x=7{D`_OFO2p@ZaR#HZ_A;4Pen(RL9ZgbO~I!c$vMGOH# z(!ma3j+hs9t7&OZp15Pi-y^`uy(n4Cdsy$QP)~e6U=f#iO8A84T>MH;rvW?@PFE<) z!*zB|8wWAox%*8fW9Uk$03!$lH_jJv?GJ2K8P9rEL1zTm1{5>r z6_3!;YVr3|f6t;KZp99rAT_Tpg@NCt6nm(s;kV;a!*n)1(on~ew#%R(NSq<4`A3Yi zR5==!yP^&>voGU~gP*u9B^OVOu?ZYPt*lFqUpAye7v3iwMZOC58}W6sM^#(rfI-I} zX`L;#X||C98rDBuM+5gRzh9LlfpGKdY(O%=^PT;*j@%IxIWsTB(AOxLdIYdVvdgHP zt}nHg5pyKirxag1a9mi34^esQ?_GgEjy-4Py?hg-Z5#7pO~7{YNvclQUUf)NFNa0E zD`m6neEzgYH%vq*IUc(k<)Q6C(f~I=$iGMIxGBq<8PuoN9P0vWlXqXKlWSDGE(Rnc z*Z05pVud&|X^0Sc!A>v8{w#U4nGTU;e`~~6#UaA(y)wxb8R)GCN<_~X>j>dE^|Os| z22&NCJ8@b!`R}$-!FK>st?n;O2reO!U*V^u=)<*`VD;SXY$A(c z-QfJAhCEnUAeXq36W?VX3}&hkzOTMsnj62ncQaR^W1tQ5wx=*o4Eibr*=bS+o)ww4 zuDrMly7Ka1gDx6InVbDoK_!)$i)~ONk%F6~HjsABL49CVPdx)uv^)g<=RZpX|NT@> zsm`|FL7a2 z5LbauWleMJWeLO9Cd;3|2djDX!Okx)H@LF*%^d4ugc~K0%nSz@(W8<>z@iwW?&LFl z!}}*>-c=omr?gdPF9uzk#sJdUO@j{vB4FG@BSyzM8c16dG_I3=X&VAe`u0AQ2n^>M z9YDj%Z;e^}k?LWdG1Kk3O1LPQA2mzhv(ELy%G!T+sbB9QX(Y)DZy$M=I9>b+ zqjR!0=)jj=?P?f`a6=4{CYF;(7o_2}0&_{n3FixP+hMKm>r$fJK#BccF!r5pQ^6*H zW)XisWL_i0)qh_S#*2l;HXgp$u;JiIG|P-@CIuq!!MOE!Eja*LVQMc$k6Z4{m%Gcu zGpg@Cj*OB!d~=@a6Xx77JSO<^VNxaOQzCgXK7F)My6Gw#IvFiC{b%W4fV~-zT<=mu zA@71-4wGi2RkU4}^Etso^r&s^WCieLG#ao6OjEH?74`_Dt;HK}y)`SNX^+j5bLZJ= zxy;a!;-<8~JmPFp50DfB`=Iy!C#a^>C1*8HB#AGXnApNob|AbP&!{Ls7HAH)U$xz= zpRlYO`Dq#)ks3T*oA^dLtJYU+Bkq>tHL`xCM$+_E(}XV@w*#{S+sJ!?!MV5cz2qAB z1;$i%(Kwk@5T8O@o&^TJ7IwDm2AT=6#Mw76eX=4OUy>}@HZdkJa~k0+%-F^0Mxy{v zTu5WA&3%`5_0D~_MQ$kh(5*J&nP>V8PX#d9KT4FhZ(5METF1a)c-Byyg0}@|nD*mC zsy?dl2kwe?JdVu@-cZ+&b~IjQa-nnuD$I?=4*ZIEai&z9o_dnP(=)>nhjd_zv-!S< zgd-PS=hc)xWOcihrqHTANIqt2pT2Sjn%9u_X(`-&*?3hsG5&kM{5gSGFNLnTw| zyqtxVgVHewit{06!QxkWQhHrzZg4g~?|>lnr{+~_UAr3A)UXQ($->BEq5(c7G5C#e z8^rl{Y!Ax0z_V1scbO9D;F8!%@3+KGJ3hbMDU0GBP@3gz;I^FSH_=ze7; zUsgbLt>B+6&K^$=rt4GX-pu7ekXw`$Zs*Qh79y6b^N3&OjgFq-4z|1T`El1Z$9Hr42HRLPYn zXi1sA+@`J>fZ3NQ5?5@?qX1U#;QM={!~SPIRXy)(-7b@UBc5!-?b!vf48z~7idqx< z9pgQc6y00t-BC@>Ab51icO(-JM{~zVa(lu5Kx;K3`(R+s5~Od4@eVmlrl@`@9|^_rJLb%H~&hf`zW{n7F7|cLP^hTDvfCi6UGqXTB)eJo;7JAXXSeXN@4RsEw0^(cZOFg~~lH zPVj5KG`NW==Ldvt^}&52fRg6-GPjwn`Hu?#`j|Zs7-3{8&2~TY0d~*t1=r-}_FsxA zSCP z@yzOvbNtSeh7l%e8u!8Zmtp`zT3)l{*C{564l?C44M1y2MiLzd*4-rCRAKS-szB2sK9V6nzwblMn&T_r0_=G}{S z1vTI7HpB9}>#WMf9BAc_6}B`22&uu`^Ip*E1{xo7hB}5qr9jsWM6R&6$HaxP6$*3E zdmNFiYk_VaW@G1|?6OpmmF3)A0FNxak2n6D84J^?zUWA;w(}a zj_9W&MT7$soA*#E{Yud?s5ciYk8I9Z*Bo;n)3Lr~cEqH@WdTrxTl-06G(ejfbrRLn zfuaEHHPzMo{J2-^IbQOT40?U6)to>m6Z9!<+P2!36^i(E0L#?KVKu?;7$sW~5=CeVrV#ckyBXRnqCm=i(AX1u zvDTi2ao}U*^EyTtALV}y9wV0mKSP&7M@O~fOHH(MUUQnae)R!|x%i{RQrfNFcljpf zSFc++@>5&YCSJ~2I0v&pt`fgMSpnh4U#s#@!d?B`wKf#LF&fSSgpz_%UlKYE`~;!|Ybr#+9S{Ogaz}lMonh&}EO}1eQG>BO4D! zA*eU201yMAV@U$PwfzD+-(;4H6C!h>gYQp?+IO6QlvCQo#0nxZQ1_WFt;zbGEd4`x z>C-RJX)?UT&4vm?Xdg(2{rm_{gv>t!N%${On*+o!5R9UvxXp&7BGLkWdwKD({0l6p zB6Mbu?OkuAB^_qj@^y=%8z@SCeJxF{qQ`h^ns`CU&1c6VmU1|np|@@Bjfz96&mou_ zL*xL&ieHW3eW1vHaR~L|4sx)AkG&M_P*1~hk=`z44tGl>l=HMVOrb;KL^ym$;rWX| zOa_oza>jCfHnkNDChzKq3$`TicQpe3U}&)GFXx87EW zlae%3-tkQ~9&q?D@P6eSW!7s(-{k&f{HT}w-x|&Uci4Nh2nagG0{j<4lII(YFtZoT zdrt=1$Fz+evz0h1rJkK0Sp2YR%kxm+772{<=w2j)G9hCuyHIVb6{uYDwdfAo8VCSaC{z1aP7f z7WDX6f?KUp?Auaew1?MPx@!4e8;z+CBJSL0S0fCMzP|O}%iQ;a(;l9gLo^XKZEOJO zEtFy?LUv71jR+P?8xupPv8Cz2FI^qMorXPqv!k%nuV7GbQ$V}Icgo}3RzWm2d1RTA z`1imX+5crj1GZC2!*BIl;OXF=Fx9=W4>Z>Y+kPFVxFzH*J?Sabhm}t3e?M+l4^okw?WN$ z#~z#Y3Nilk^mV(to2>1Nxk(OV0I{4(f*m%8W)gDKP{uW%RZU9J!P_7=6gzo6pTO#x z9JDSo-yos^g$RDvKDugC=pJL4fq&IRV=T>8Wq8P7iu6Bzl20m-A@GkA{}a2y_uLVB zH!+*jsXm}a;PX{5?nDvyMqqy1k14^GVoR1s^?9S`g%fNx#5(s`GC|$6zk$0n1Sb0s z@qHs1Uzm?E;`%?g`?D{&7e{0$rl;b(lQ~HDAj9Xp65MG{^A7f&q1f-?LLGceIo>rV zl4Sp%(&rHzTSE%BX7UOZpBFw_Q0icxc z&1Y+1CtuqUb;Vkh&@v#EadQXOE>#KxxmNV61kuIGJdWS&-@;>9E!G^gn}15L=udDu zuI9GpR_O~gCFd89^TTwURnd!<|FfM2C?vEG-T|d_?pXkT%0|V6uhA0MCA}0%f|zpY1C_3GMUzM}4w_k_>(BMNL$EZ zq}=J>6U*}^YY+NtK)Bo+!68&Hu*lHSK%{m?xy*E@WtrwIh31ECtEGchOlukNoJjs} zkYqw|CHe$eRCFvosU#^xmVAFIz+1T(3O4I~ab3r0<)knHG;|U-&mVx0pWKsMwu;xH zfuFi>6ND7i*yAjN4yOoZ;M)P4{E~+t4MRqtNWe67fM%273gK)8Xnw_od@k!ik(b_u zH^W8(;J)qoQPKumLf>ckc zmzP|;y)^Y|l=0;=#)@HfY2r}5=6$afa8o&!94^gm+&6&map^AXFL@*u56C-7_Vj{g zqm6m{V&%GL1KeaLnGC_GOVa^A;vDWfknKV%w{|0oJN@`yyBI3e?j=3 zjQ74ZX*mENZa@cG8m59lSs~S>Ul)o6Z-Va-UK+HM4!6eb?PrjR^#taqpS7fsV^y3);(2A3T1kr=PP;;=gx8b=xMD)@uOYj)*NQC;Bh_%E1ln(QYl zuG~UDyrdB1=9^P5r!)ld87kwJr*3;~G^Y<-EB(a9ZOk1UMw;S8S|>${ z_$v+Ds1s*T7ho11z32VVy4T)3<{ZVC2^$UgYr;n*G3yBy(k{CjqV_hxY)PQh$to^PUt20P99^V{v~7_i#U;yj)UcO zbX3m;nTyWXn-ASIGfUk@RI5bRVXr{G4q&C4l;-D22N+7=`aPt~^sUC2y|3PIxOgQ< zhSe{Mz!q<2bmDzPQmLA^KbBJ-zeRP_m)jWMynW62Ea8J$khH|~-~`5t zG4qoHX>oR8;u)%?!yBLxs1%%a9KWw4Uz_V%Favj+K-5Rqiq@%U#V_BL!h$wi-teEo zkM`p}MRLtUBh_bBBs zW~eIS#B@eT$i9xJY$FUczwfuCyHz1!xMTKjEZKiPtxKF?NF01a*z;qrSM@J0+0itO zu$1NkMS^qQ_!9?DujRN1LSFtapn}*F%V5s9t0d`-M%TMx}mEBpsLt z2ZUALTJ(5nq*mh`*xaG-5_>B84|iyq|2}X4scCZbbY-$!!VYCUX0@fhZaZ|}ztmW} zM_`bbFIYJw0O@@a^mJL77UK@qwkS^Q2MZm1;M2TC6Sd${;-eG|CWw?htnXR;de3WU zh$>u@+xR-=_>gIpv1Qk<%gN}*Lx?+v8J zXG-b*En9XpT_~VC&F>XHo!>uob?RcRT6{%ud1buW(DA>0>4GJV+z&h}VrT`cuyt`0 zOvcl>IA}1M4T)NLs_??hXMd7&i$pRnstCj&_0&Hm% zxp!tU6f>oq6|h%+p%YdKqxeVjCN?UA?am1DS59x5^b9-LNK}TMsY9{?M~)m7B>uuN z{wPke4dfF4M{-81=M@ChDi%L%x^+y7h1#XQ+DF+5 zac{+SJa?Ke1Pq)M_UK4_Q}CtK8%jV8w=P=%@Zeg_?d#SCpnQDo-wF# z{AR2*)Aq~qf9eKEx;^u#Ixa1R_(@wBqcB=?7vU==Mu^8iOtHM(6*k3(x(6-W@A1s4 zApIl~`kVd``FT@Zs{F)=RSf+V6YVg{I$$O*NT8rH`xd-}^AW*#a|KZ0mioEH3g(G_ z*s*)05s;J;O{!(ouPCs0tUzH5^6;5^tGgz?h}#;yPTd!ik!7WAn2@Q$`}_TUZtfz5 z3h8&6?~xMLCgJ=PlIiuY^=G6W?Y}3Dk-M9OS}hbx7kev0~WJ-K-npuz0L`|5pQypWV!5O zs5z1Z4qdSKr2yh5>^&FX`eGnNxF?az9#&H^`H%e-z^PCVGrvd@?AVkE_3Q3Kkj)?a z^MhSl&x~{pQ=Iktu9T4oACtu#&7bP|jQ(+aJ?7J-{-nrv*ibHm;>)F>8w*adJp*hX zzz5XZ($}{?J%|b_2six=_~_6sitHg#RX3ux4U5wgRaO?F{C#s7RdC^Ij$zik^(J{b ze`?z~W*yR&{q7iYx*?q@FSofECncdE4XD3Uv0A^nAsAe7Mh?$SWY-m#);>ZmH?D2Z zuf!F}XEX`-kOEW@qj0r*bNrKlz(^)9uPD+&i}?OyHC{B1lA<#%k*F})Q8}?(W>p`*3=# zc7KzC_1&w0I19_xvYmMCeK-7WjRk)WhlXNoh=zcExiGkhvlc{?_PS~2ubF(0@N`{y zQjq79Hc`%{3eaY$fI*fEG`uewh=km!gr?gYVo7@A{e^gKjnF|e)o<-i-K*T{q~?Ij z1F?WMi9S_m8gtQ0Bng>g9Zl?6>nlTv)TZX0w{~wiLaA!oLencHR>d2Xm$pLB;X3r} zeBLz3k;h5 zcp0o2kQVzKo2awF!hGr~poRb$y>WNNwdK|$4ThF?=T$pMhuVDO+^-`Ku_pS6Lq%rPlKgEIE3;uVvPI`!4$Z3nUSWj zrBJQIlzjSCNMs9Cr$7VLW9hFdSv{3%WiQoRRqR*#x@^qwwz6uV8~3EXB7z-GCKBTE zVybqv-wqu(ibMQ;UkeSJpFG_9@BLan*9NQn#EE`i#V-;zfmjyJ6gu^UWI6J;Nu=f( zKDv+m6fzO_i9ED;t2EEP^k~ijx*KzQDo%HhbCV`96+hqbm}%=Y>;yfz3O*x7XAZJh zrMz@ls0z-W7_Rqd5z0(|G~JAcV7+Za^PhYq>L0=w+Vn@%H8>nfK|sR38wiwGBU}@&BiO0(EU5ZP?!T5($39mr zntzjjm2h0{ga*riFZSv`LQo3=Q`cVR3mwWgyQh$BC?n;qWV)M%*qz7Tb3s>x|s@VXtO8NfUbb z9@cbX;OF~o58D*9&4UJx+lxARTaqQ4OHu}pWs*W}yNH;LVI;c7UyRe&tDcBvz1*AF zQ}tguxWgbXw%cga%{1)w7fcy&A>M86b4ayZeBm(zO3oNo%kcx4 z9HDfzkhb6BHy(Gy9mA_#en~Fi+pF!{1)V;WyCvqrc#ofYw|5~+e7k}?X}~Ne8nawH z&qlCwan1F*PpZ+7n}&MkyMFsPUkb=X2SBz;b78mv`1=O6`$bu*5~OFqR&q+Gh-P@s z7&{=Y2qQo-59|#E?mnJi+kYGA_N<#yCQ|mCfJcEC@YJt{Oyfp5BfY_+(XXP*ffS6C zWNLT&_zDeo3ojlwaklJF5mIQ=DdG4p(SV~-ki$a)K z;x{~&sOfz}yNjKQ;;91OF4haPudwl1rOFX>cbpVxcrl0NwZgc)f>uy!&YeP+xsoHy zcp&c-I`^N?I>IGFmE^;##G>CoW=-n(T&eBOc2Nk$VW(K~b|xDq!1_?1kt;tu1G)O> z!Hy3y>N-GacxO;xW3k^a#Qo_7AQ=Z1Vr?r`Ew*kcPlt(9Nh0NIt4vn3$M$IN7tX@~ zeU-#67k++2XePxuBS%!yV5?}fVNv_lt#QaO{ggG#uz!x@-l1Cyz%r@=)RFQBsb)c-ekH9gki&vckCYYXQMkoATp8u}Uso@axcOWwPc^t<{o}+T%)9jRsM|ILR z?>?B9938aRyh?JOe%$AB_+U}|2;m;LdlAZNICxNvhT5wQRQ=3g+`cuj=&%usPJC<` zetFPIc~^OS7*=i)B?la`Hj!onUO|K9EN!QM^~OjetU+0Z%|cJ4fbnthD{fum@#-q_ zjO9rPrIc;!awn>N8a4_vZdwb_eB}aG%?O}ExXyd~kmUnt$%FjzW;aOCo@7E;$W$g} z$C&#Rl^G`d28e+IRwp;%hT0gNKJNbv#3`rd#UWWzfa$`v+Xt;J&jq}hl&G-)B5Mi@ z-XLQp@&Q|m?fa6T5}6r;qS8=nm}oQD?>{#)2s7itfVPMb3Qm*k*Xq%2ZmS4nVvMan z3FLNYV63&x*R48i@Y4H<%(Qg-d#he45>aeJackh)W_D+ibgdtGeNia%4VmFVuD<_r zx*}dJ7VM@sAkmZ1ecYOQ$k?zloDbmKgT?Dw0z#O<*ntyj9z7Y%2sCGj-?$tg65pPJoQZ}=Sd~v>_RSU_WxV6scy4mSrrTUo;YxLU zoW{R6J#aue{hpd?)>RW`ugNei)y_*Kw-cIpX7AS)Zc1^RxV`|p&bM<3TLAAN?O_qJ zZFaapZL|WsLm}!97KJ?50td zZTKMLMo^M<;am%!m9DJNw6)Gkm*nil4D~}vF$}ie0=r;8We7AWCtuoe-_$icL}pvh zM3zzhQXZe>^SUP>S>F~0jV``zD6@$2$`@J7)~6CwjT*0VCcD&!@Cq95huPU|t6IUi zdl!Bp=tRvYl?I4<%mp11b?xb?&R&u1yDT3W`;t--E)@bMn@iipD?+t52tO+RYSE?S z$tCxIq7Y26_LcTpssHUgDN29?p-NhQb;&Uv$&gq*~F~5SjHi2_}M9 zsEvm>4I!%s=BtlHVUxAgo0z(y1E2ShV#hewr#g;grXZ`x&R#k%Ua+!+ZWU^-~u7 zi{PosBtVrhFqtoTx3$h$p(ef+u4tMc4)N3#X^(T0={{!KJ}KT2fnh)PPy3Z-_)&L$Ech8}{) zj`2nDs$L833nM0s@f2PQwcHGbieh-tw(5pUrnkFL5IM%m#7c;-OcGPMWrg&(R zLX&e?8q`@8yX!x*05CS^dBhKrRgXdBVK7K)V6`41A-6#YLPM`pa^H@!H6#=NNqV-b z`;_~)VHHM`=s6HHV2To14Sf1BwE61&8g|16nQ*h-PS%}E6BUu@RKVK(0Yo+X3A$kn zviW{3!h%z!qwPZJOx8ZOUrU&5Y$no*bFb-mI(wP)BN1s}R8k}Io$(5%sW%KOxDJ_BTA-L4^e5Iy;Oi1b2xqmR5mz?K5MCXdFJ6Zsy~a71 zq4dU|KssgeTRy4&#pzXLP&S1(=QcZ3lCf?Rd}^UpojFcz03lEx@xUgsJPBBX_5FYr zDjM8ggT?9ZMp6ycpKDCpVdd$JL6;tH@;3NeVG<6%}_gYBkM$nz|V_t++Vx90%ZF2L0RFQj|i8Ii@-aa(G5p!aIxAp z-|qcK{Z$Gln2;+awA>6*&Bl*EXugHG=Wugooygz)duK|<$>-f6c5UTMg>Fdw9{ zl+7YI8dd=Wqo6#KBr1UdaNCZ?nr#(K$?f_J{t9nYV`xrwuuKBPlrdrKv_nqF5G9zr z(o$wcQ&J#!dqMz2ZZM9k_H3m+4r@9ZAer$CQ}Hdn&9Ev7Y>tUqARA{%ht!FmXrp1@ zJ5(*)3w}?{ze<`e<$-%C!!VQKD5G{3t>(L|SXzn<%(h@nvz@`B`hX))1!4c`L?wiY zm$JDne#NtUVR@0E+65OMiq{G#2X1jD5-GYZ31HJuM7Qy!9lpK=I_AsR;9F)K3#CL6 z-`9ca==YQSr6(Xf$2iF$Q9=7kM{53ecqG{9o+t!Lsfr>Ei`yXFQPO4^*SCYypRb8C zWL(Z;LB18Sj{9rJMtWjsa4!J}&$tIA6wW3FwCifPynEoSCOAQgj~I?m)n_mtIx3Ly zkaiq;9ZT8=S973ghp|Prp=k8OpQ5hJs`#I4DlRT|nMfF9_8BBXdqiTgu3R=EZkYt2h}{T3 zyR4@ac*Qd>)X&oN+(&A4$ob|o5^W$6#GYNV z+E`>|l7Gll>xHidK7xi@)2y{Qb96TdH0EU=83wDW(B*^st5Az>=--u?y>#?s9`xg8 zBY%rqLx8_~*UDP8-$BjN9gMozM%$U^kj16%b9ml+cAs7EVA&zV2{^lPdK83)4Bp^E zG*i89>0TTjTwP@4jXNNrS?k=|asZ^!IoFedp)ixrCS4rX>j|pZuv)96t5Hhg7t6NY zz>IxT4`EOHEi{*UMdE|viwdD@LIyl7_ZsTh$&a2hlI>=zhxl&R)rd_-_a5;xr^Wek z77<@s{ZUou`umuaX35SrRD-;}XXB<}FWPw}RtW7?i$u97IZUbTDA1{tY4cqW5V z|12JEnL~7BG2z%==}#UqNOo?p<3`UCI%qC^NMV@*R z)+)DDj3EI}b{HYsFM~>DqKoRktDuUnz&mvuwd~HUwwYO}` z&e6Yt4Gd$T1_y`N)18dv83^2~$)wp_LiJjBhSCpK4c#?Vc7vgv9-oCisX8JwP`L3Lw*;kGpm;ygoHnFh6IxjgUA72hr@N7IOiu}v3 zYE(uxK3PMHCQmzxX*<;XTZe;EfBdaz=aHn);9u+ciDj0x#1+NfGd;7~1JWm*31**w z7}fV}NdLcY%i#lB(mI@)ayKI^x@j?nhWG&pZ0YOujv&PaG$_hx5(1fAkO#BT%io>L z5`s&^>&MVA_Xi(v4by(5JG!4Zax%M#xbP##*hVi3(8e|#bqo)dQq^jA7-IzJwvu-u zP9EXe7a)Q8LA;{~6l+^Fs%BE(SsswXy#Hz3bgQ+(7Q>&uIQ_`jDgFfG>4{Kr=n-fL zR59wLo{REgWs^dPg;M}T4*0{Mjx#UHv$5COHr0ALQO&__azvi$TlBQcq*WJsLi)lugvn)L34>bp;9h$k~s$voBzoWH-@qW@21aPFvz@NyCJ>dhI*=R^#z zgn((3*)9?1BE7Bc6tEN0WI9|zV`OHd6XOO|Qe>7{^hguPF_0-aJdKC&g? zT0ghM5$wU&<>hofdX?p$CTX5PHQbX!e)lGVx$~=)TR|9e0Hi-)H2s&yjK1s*$hJ0Q ziHKgpy0D=AtBWqHLTJ9+$=u#SI4j*plwn>A*B1@qrl~U5;wQC&t{sZLtsli z%2fZV8>&lK1N&aP*SSkkJRsQ5kKDtJoy*?nM+#fs7Xs~MDDj&pyb-to*qiN{`DccK zy&1<*E|Fti@jAfWd&dHW`YC^;HVdl+r)6hR^R&$ zgm_W%=Zj<&z778QLE;Y!eA#{SQEjRvg5-0M!jJ+Xt;el7+XfQG7Ob|8p!H7v;BfVBmgXGzjpu zvqvP_vhPAH_TiQZH|Pl~Q^lU!X*jmj@4rqgRXL@u#X*4f&2;B!;Gx=5hNDf82XpJy z84Est`YGx!sP6FmpYg#-q0XQd63k|6YXC(`ag0)?$>F~YZllXnpsoR`yS>h_w`4>( zL*|OUPHXOl+EU+ZM0{zmSizs{)f&}-{72-0w->t>F9M&dHCJq+XNwd!WrAV_(Q{OM zFDEH3H2A{Q_z;St&#WHoEHh4RTHTaItzN7$MK!JzWe^23SiWpILl7xw4y+`}&jc}k zFP|lWTePYa21Vik!AMoc!F#dq>7f@KAPpm~NQ+JehO3}!Nvl11^Fx3{n5L9$U0hH` zt{!NicSbd{!-;e~dKVM_l# zmB2n)jBVTPnBsD5zM9$(RLvb%a~$x3pUhlFveAQTsfSx(Ty%%oEr6-f=?uBHu{BzT zb9yYF?Cjs(rdSP&%;}7E<~9cbxZB=gd8*F!>{liUr;DO&U5vcbztLO;6l+Tb0qBodazWX~rI^`dTSw-f$*p+uG1id0n)M+>|kjoPmW8 z1Z44xbAwk}{(V1Z2Dr6(4ebZ_kk!EW=Wk^+(u)w)!7hGgFJM4~F2Q@^DIdp%52!)FgGxrpr%uavHt zB+IrhFN}|7ecp)i_~g=4Z^X z^vH4Wer#;J)HI_)K%_+Qx5PIWhs%$>;X_?G+A~sR_k06Fi9p7?>9G2XEk6r6?}v%^ znPC|<0_ivNG2!*07CAwy9CnetZSsz?5Aeg&CIy$b=e-dy{TGGWWi>z?>G$7q0`Z&< z8>_iY;4R%&F>@GSYf;)Nj@r@)6N{?)wVdYkYYOA^r#n#|Xp|hQdywjr;ESi?eJl-0 zG%575#47#hOSm<4$(((Rcm-0&AKTB!AJ&qfe61JJ8UZ%x3>gg%C`}R}{HBM>-n=7j z3et?KrzIy<)2te@vn{Z{{mASW3i1i(nD6Kd!}ODi41kJ`Qvy#%V)#+Sh{)H29ml-v z5B$%Q(2P1qdZJ7~o;*$D$8OD4uqKFD(TA;vYc+9_fIhw2F|zr&#Vppt(~1(+4)|e7 z*1;vdJHCZV9`p@sbi;Q`msNu8pc&wCCAlH{Jp+0FCn*3_;<0IybmdNWeL%}$!otfqAf(L>s3Z48Oh z1BXdL|ABs`*mt9!x5D*S9AxyY-XpNm!v$bc@FXlY!OX~ObE~Z@X={lAmwfU2diLl) zL(d<K930!>CGL!@^JgTuy#yzu5b7764ir zhezg8K8p}v%^VB1P6tv~Rrv%wm0XitYIAJ)*B`-A^-4XwbVXyXXdVK z(tQ~_Spi132XRRUdHOl~ETIL4sJYT;%Q-49TzZ5MFj9LyojfL*Oc**bD`$W|A}4aO z;t;e9G35V19{?JOH52)g-b;Hlf>IGUBj`o>6GZA6HwW^7Xjg}dbTLaj*u}8~Ny2mn z{f(4V$u zM;cE(p0H?C^)rOk$II=hovZCdz7xe0sO-y`~BI z-BsFW4_G=Q2(?g`7Cx^0RvVni$STV50dO1Vq~_YPVWS{$FLII9J#*;8>DaLtKh-=K zOg<$RY%Ik@OEGo%QdA`E3~`yGeSf920;M+$Kv@H+XDVyK;m2+D-f4hI4!mqYdMaNJ zBxlhnPJw}^yG!O>K09ej$H5JO>4+67i}D=-Iya8*;@7564RHsvv%gbW1}DKSw3*5L zKFg-GXlGx-(U82r8YAQunZvFzNt-rIIY^=6D#}pyR~3zjH~pr4~<{6eoBjvg0Z09&7ZJ#CD+6uT6n1tVR*s8buJyy0&_(>@-79^ z&$reM(tb*4AXFVR*y7TI<(3p6%P^sN%>Xe#&cD8Hg4wAPK>8=I$kdL) z5H7gb37Sx^pK`Sy0?Wud1hEfjiB{E|r+ClBHN6BVNqR`Mx}dM~1BI&@@Ut$&r*>Mt ziVh1e%@HpK0V5PjSzqs_e;NM^guWF@a+hK)q~qTy(BDkcqc$t+zYR!E^9|7#IGpHZ ze8Ha8cpWY9^W|*XquwzL*;e5tv0p+PhsqPO@i( z5-Kj3)^Z>#_uy+osv1#iRQ#_C5WXh3jS+}h_l7R=+atUhRWjbfV3{8PXu0VKUT?phK0(Hl6Wb0 zSd)?CTg5sH{k0m|#r-ya``Y@<>OM!Y@@9ayS6G=Axt}|Q_?9!LZ>%OC5ZZlIu8{+& zET*af8G}(?;vHj928s;dQcrN2>c&4pLGY18n{v)P>fC;HTo#GM?+2%nEc$eB2c_K! z__+6DZ9&OfVr$TlS{%TXgkfxaW#{sJ+>3+8h3$lwfnJwk=2tujXhxv#7rdQi*XMOU zqj2U!7@M7*Io}Jt)h1@skTo-n1L5v`{6Nt~bRSCRb6($@EwnFHXdWvDXf1}sG&VUQ z5D>{wNQhbrn7$Dcgc^0fp@1Dcg{xc(^JJ`wA`@-67cSRd<6J^D!mY2m7NjQm2My~p zz}w6@9vyOcQ^ZFhNq9rw)@qd1LTGKT@q zo7aRWLq`?-_(T<@xeLnt{(iB4D4C!F{!I@*uMt}kCi0*12 zUDi|ka~ZqUi^SsO{;sX1a{^BX)HeUGm;aQlUll|R`z~!mZ+HUny&oH~Z0*E8lFf7! z&Wa%R0Tq%v5fZVr%{5kwII=#V$YLILdwdJL%Bdq};SVb@t_AbE9zWJ6;F=@QZdG^) z3Tive+d78k(-j@Uhz7h&)_rhsM9g$+?gDbq{XuPEBzU9Mv-ndBX(yh_aDF->JkK9? zF~CF1)pz?6Y?Z0WVnO?ZxsL1q@KmNvW#J>;+L6r02SrrWa4(q!@}WgSv=utG3hQ7iUdl)F$-SwoOW_8djBQ`7-v3OqB|) zQr9qr#0jUM@^2cKq)n!w(3+E+6j8@tI?q+H%;M!DqP&vZ%RcpG9c|+daQDiL5x(^@6S@ja2d!K+nYn76#RP{|dHXL#!0lDC>bJ zBCaum3t6!!PFQ~LhPm^mPt|JYjU}mm`1Ev!DKtVmWpQM!8IAhwZ55=sTFNA(5S2e$ z6jy8*?>t#b00mwTt+dC=;&%%P&3EikJTsVq=PuePkqPCuGcJ@0KA^Q=XrL%vp{wXf zQdbfsAS`?tYLPg+M@m7|ugksW-XcAkJUUqhs+rHRT2_&6Qc2?$$FW1Qu9Ai zi+@aFNV)aNtQ7CWls5(ddf5v(^3<+ihy8As`PUc0>d2_CTG+{lcY&C23;ew(a1tH~3a!eOjmudlqt5I$PK0t3kuPZp}$4<`iOagkxp0;)Qp9#GvLw%?y! zpsYwO)T9|Pk}sDs`x2<7SxnMl?k#^J)Wf)O~a-U)oe}Cqn+F$EbDac zHg+W@?Bn;fUP)hJpw`<6PqpfjI-8569_D5@&6y7t19?!>0;8e?8e*ViAEU?GH<9F* zUG*b6hFkojhPq8(#Qi#ntQ{z}x$IllB4wQLPd%@h?ka`)(#CgiLi3AU@axD|r}+{z zSWV>Qs*(tXci@Y>0O8w+$9!mMY~u;ChpUnHJ>!khOUHcRN7{(1-0yN>Ut+k3t+G!R zu@Q>gsjOu^GMpMvcLwCWTtb&rVW^hO74+DZPz1-2tHE`R7D8hK)3@@22$Cfu@c$(Y z<~o%&Zdp-HxsD+U9VCD-*${f*X431GI+R@aLM6hlh+JJOd%teOYfnf&)9nX1=4dVz(_87}?-Ika6Vj5YB-aM&pbCk}-4Zo9ntF2ri zPcq~*=6#h=Tg&Vag=qiI;baF;rrG0@$uOPAsrYsEydxm2s10ja$sguKZPYj67uQ*` zn3~f`b*dHuA~2cf{SH`my(HzDmS!4gmF(`EC``C(b=a^(SW83$w{0^Wjr>y%wREff zBYQ}5+r(suf1Ax^6@1mh_R6UmuPy|m`gdXntoR!Tv+?1K0Wv{0;}MZ`#*aF}F2w0+1p?+#zD z1aaSAJbC>6+F_c**_S*J%DS*>O~6Ss#jtaQ^_PLD@Hqi)!KE0dUM3@(ybF4}GPicG}|p{V0d!g;`aL$I5j4WuWi(ARDa@9F?uytWHBtJdu(+J*ecVE|0H z(q%YlK5bpj<=rzPc()hMJO_X=5jwN4G9{uwNM67lO$X**gB82&2=QW!YE|Z#=e*aT zhjsGGCkZzs+2@K4-}^BJAoe|RcL5UQ1LC>2Y{m{rxO2c`;w+T|3Z6LWL|i};XR5?& z9`~{(9Qa2TY0&O`Gh-9Q;jm#EE7<9$>z-q`QjD$eD|dpI}+g*vnB6M3^_l9 z5+Y_hRpxgS6+!Vu2dTLTkQ&Mt%#Uw1KDIKf_J}4wZ81GbGZlBaKuY`MMK%4DKI!pz zMD@v8q?UuCK3;CZG|F5!0;UTDZJpGuqaQ6vDt?Y;-G{Zrh$l^)eF8Z<`PYJWb}mu0 z`LzP}X_TD9T>-tS1i}f#=~5v=qs_zhb0=z6Eod{Rc6(3;z`#W?*BgWn$XR$2v-@^U z^k387=K!;}1~e>p8eRp%(9Kwu(GcN4)tHZwvleqLI(O_TVn>^e?7|21x$^g{Mez>C zx5hkpRsx_pTqs^RI#M z@vR0*`zAhy z!>gd46Rf=GTb+ut)JkHBmyTT2yjPA$wfX62;#^+joi{!hSW_r>wF1G}`L4(tK;1*5 zf3J<(>d55rU$nL8ja-%tz7HpxWgH0ylNU^wB;-Seo!`Y)2+1theU<#%E^mnue?P^5AXfIDPmBtV5CQihdgl%pylW8{1@xna zNM{2#u{LB$KeVi-EHOJNdw@##-ar+))TrnNBFr>~0D8x?9YE1piHOKoav$PZ@D*X! z3J~DPD5lo7UBoy+0ztU`*H@Qm0znlFlSEViw2CN5&k#b=-OK!Q%b23q1=0Cxl+Di5 zSGB+!w)A)yPuaec8{nVNr;~ijI$7k{|77-X2S*-5m0p-K832XI)2AYkQUwFZr)t+h zK(cx_i+q%7X%$LoQfbhgbYYsHDi>w_H4p2dbZS9(>IL~Sr(&h>U5VUg(E@gtEb_ZM zf^b9>RO7~5!CQQfWrNFKA7RJfe6%(UnDeg!`EGOn?y&)?sz3ssHvbz*4gC>}8@Jar zQb^6_TqUFvp=-f)S~R~Nd~R0d@_CiIkfW|qzc*;bwHpf)CzFYd`fuQwDT|5{ajLog zlod!knfW0dd7VXn7a`fN+o$=E=r<==)uo)K7&!NSp%kj?1EW7=5gbhdWI`k25Uh9x8d(-F)a! z>moFPc@*F=)&fTP=xn6st*8!Znn)#yuSWdN9G?&%Ht=GK+s7m}ta@ol>d&lPpYJP! zjUVkgg%_zMHr^m{aaDUS>*iC0Id``yo7LB#h?=u9FFtRh1up?i>%ASXoc2FNqrEwM7bcts+}Zj>=Br3Ia(DD^F7O0m9XgEL(KK_1MOb16LxTdQ4wjmRWPiG;@I=PJt|wbV3n8W;y zpy+7<<6vPBN&5A{ka6T2Emh1(&)J{ukl9DtOXbq>P}x1pWeu;TFQeWd@q#yOVom$59?{E2=lL8B7S7Jju8azS^8rz&8ZZz1(9vKn%JYNUW2GLNdYRz_|J`oISONDNq>P-_zk z6nifLmf;kg9Xt+O%|`YvCkhuqV}DCzujSED^vEN-DQBIif-Wi*Q}5uxbUlHG&&<$X z%d#pJBNkIkVjj_D?V7QGZD|wuMz=l=FGv2{8-TWHe7QD7pH>y$sSWAb zBjjkV!;GU^hy`EYd*eTPnx#WUysZ9tH_S zpsMj@i?|CA^O156M|LoS0zTjoN3qxn{zty_QCoc)txDU{mdgBuL*QaOw`ty8_TftE zHZ!SzUXH#v+-jbVlC@Dw_alpT>xz$>2JBDCi}MXn(?adp(jRjCI(9!zy{7iJ?5rP? zT|D$1*bPKw`2NMcTx=cDSF7U7cXPq9 z4BEGKk+cuAnv!zy)=8D*R-ja2RV#`k2^lID^fYe~Qd&frSBWur^Nq=z68GEIxh{Wb z_>|)rE<%`(`41|}t+DSGnS7{Fgs>JLm*eg^ll3LfDF=6C-I&;2D3CENIQ5FzDe^h_ zC9M~{Fj;S)$Q~9`!BzTkzqB41*&|eP>zuKZ?y6bQ;DOW{h?SffGPEgV2$7wBZpG9{ z3>7-^A@$)m4+25zF6En>s26>XSB3Q$*1Y$$(?Rky91STi6X%>ISLMMrF{wx9`A>Wg zhyvPw70iMZnPo~LDp6C@nLG;?gQ63$=CUH^r{=gWU-f_&;Idl!K+F?c$I3jU&jPUx zv1{A?FAMXx`Vi9PB{UyU3)U0WzTFA`5*3tkMbAd0DBf~>W_78@wf#v)SF%HXmAmt~ z6Lcjbiv!M{KgR4JCo@Mr*A|35p$;REmHz?B^*(iAm3{8)5F*T;>V7h35!97GNxS8G zUg0{}4nv)P_AeEr;@#Q-1%S+}VihaNg@WN9^43N&JBaP>voGZxdIw-Il1xF>DMmPQ zA}cp*e_cW$RmkmN1#{Ri>$kqE|M!0~M!WFviKv>Foem|SI-s#uq)`^?^jwiq?!!7o zI%x>0uUe+V+W8;5{Mw#3v`$H1!OxtBk`no`ELksiEg8N86@#Z?qeYVCt(4uo+M8g5 zqd6G}xWM8`(rN;x5tZb0VxQZ=@kj)>?2pEBy5Q-R^?s;wJHsu9d~S}c_e&l0Y>Fyj zA{1=5ZZ5ZhF`zx5y!=@pIOVn>fHp-dEa%e$2IjDC}WX`jb3FLjgZke2fzr%>gl_J zi*7rr37rRHga-TW^Kt+5C%+YZ-XWrqE4crcL$5S|>X>vc+~_u{nVv6+vk!vWO_m-K zeZIHq^|)xTfhuOD+FCl!N%Y)Trr@voC$@ORrZdByJAsJjICZ%(qIGMHr6v8PBRd;9 zK|VKhn;Pmvc&#Um%w}rDRwxQAzBqZD$kvU80#$|4L1E>TmfWN)-OKZTs%5F|IxQIeI6^41}Jult3&8l!XIddyWzS4+1}8qv|zaI z{jt%rh$Yl4ldLzzuc)BUC_U7~)D9F~a6%Ht=ho@8N4E!ZU3B+EG|cop)-HF@(uRC} zLeCyueu*zJiA>4su($>b7(n*e`DpA7_F>}QR(zX6KSA7gCNIPmwQxzhK%u_a=`;np z96JY}j>af@5L6}^kHrTdjV`<=(c!)`HC_G%5KjsZwa4r*}k}xzjuFGMz(6u zlX@HW;Vm`~T+N&Hkk1{{FO`1yLS_W5VJ2MQPZ7OzzXheVe)H<%HMTIqh%c|^L2A&JgL$i?Rn^%2+WM9@xZfFfyK&wInV@naM}8R=`V zaO46HWlqvlf8hAvKdfG3Pbrv3Y9n-vm*3%^$pPa*h6SigI`eVmy)yDxb~#VZKA;8< z&wE3~+&i{rAs6xR1@~TH->xq^(4Nu;JODOle2d1aXG6@(V=rgmGQ|2_0M3GAnl({< zuMTK(UEjfW{Vk@7Sv&H~6=s1t7y-4uR;2W`??^t5qSVs9h`@5TPTCO1zN0pU7VV~r zbT5fW>c(7FV*scqSVO?;Rc-=lj(Mx0ju(mWxO&f+6?xx2CSsIVbi)Hu#j;Cw%ps@% zFg7FsI~kulRDC+j82ct;ZzJNY)&Fm5^k?(k`#;qgebB~@TyPfwHDTP z+*;+%jC85SKZ!ZiilowO!2h+2?6yS6(&Iz&M1jF(K?X`&asGenYAFen;W3E$r{-;) zUQ)J0-tS_V_c??iHJ~4hZ0SnboF(BRIw;``YR@j#;j0Dgv2Kk;?WzqwEqxyMA zE<<#(#23UFiU~ODf&leD;I|21wk5wOvvqw2Fds5=PpN*!-M-PvRM^WezMe{%D6ji> z&38oLg#yAY_^zDlz!fqS)&JF`_!MT0N_=mlb;^&1sr-p*4;#R84GOqac^k9 z3VV#t@H}GFm4n5-21}7EO8ax^M!JI?<877~3)3r)OL?!&j$3_Z?~Wam(idL3&BY_1 zO!lr1uxVkJuODsRSowub<{I!HPRBrQjzmaNX|xoTR<3hH7P@0+&YL0aQH{-|I)z{E0BlbnWm!?T4xq(A(BX>pt)Iz0i?V1}yUnC5LpB&-d z!r;swDtrAK+{dLPoxj`_!$Q6r?Hj(`+=QnY)IUaiFgaGBkGywv!cJ7c7~ABjDqJjO z_Z+dCZ>wTp&mR0?*UG^&D3%Ao40Lq@Q^T)O4-OW}Z5H>r%ELf!FGbUK7@r{Mvx|C6 zM6bSpm*%Y(r4Bi~u|oi@ZRX8yeHkR#Za6Q8r;fbq{e~Owy9&UUd(7ne91J>T#0_lQ zNY}oj$7!2~9P<)Dz%)v3!J{KJ+wx+@8sV)2lpRm|1pRYx@K;%>rL+!oZ;YNDaK6YS z>uI}255E3Ekv&Q9W)gcXk(lL_hJ7bQT`cCFTUKNC3_-(r8oYeHj5cH`gH*iKB)PLo zup2q>mtpWSTG8Hn_*>9c5ZgiNDVYN~s-Qsjk8Aw(R27w>E+Iy^0%vM5v*6FDwQ8Uo z1f}#t^&k#v9jCgDU}{TFm4#nBhKma7r@RIMvwRQ(hIvnv1s}gCFFLy-9>epl_`T1j z^cFHvNWVXy#k&DyMCqi$SW$=`T8p|!^I)YZ#gYpoSgAIoL%Bj}Px)GMSA(;QRemKG zt7HeaLvU(sa7NFlu0^waJtbhxVB0f zF%0w85StT_rr`+>kr8oGx2;*$@!|$^Dtlxh4H)_1>9<*rao^R5U2tYTkYlZ6`u_Ja zHAT5{{`yiyG`oNHQ#s3g$KM*5-i@~N`IA%r*tIa}8oWCR3!@u|>oviA@Nm^{klfG-S^z+A~4OKB2?NTG**aEV|uBGFLdu7qj{v z3J^?534^Qh(yLv`iK&mKLh`AV6D(_v-hb&J!ZP5C>M3p63Yjg{`WVYaVs2XlUra~K z$!$W)yq@N#aH~;!ty|#)q8*{$gZ!p$k5__glJkjMYJ3el$0{-_`Xp7t#`f`dT2}`P zu4}*cM7Ty3a+M^;a*ZEgYZ1u3*3sSB3&KFZEQ0M5FE>*gf<`)JEQmDU1R&m~d`GwE zfKQ$v@lFgt2qVUwAJ7@^tfAT?WIsy}ZMVi@Hx1ia)6L99Z&}n&s@g1}AkM3`s}ksN!Y+w7{t_l2fDvmZ}P!W__`- zxYM7cKgOt$o~d&!vSK!{r+oM`w1Ax7YNZvC;)Z`a%y`q7+OFT?JihqYIIRa##uxN0o-y1NF;8d*E~m$B9c)`o{S{ zFga6?YW}0yjF6EM>k>)l@eyqX-Czpms0W~Ph!hQbNhVcL_E;#J9Xv8LR5t2WQ)FRB z$zWli#<(Q#0~E|!e7OuE$A-_~qIoEHU>IalGB0oosQV=8^z#SXAad!H%A4dsWWd>0 z&Y|-U7ikP$I7T;7HmXiq1#J4z2}3Z1X6sAo!nJ5C0SI21%qQt}dw)t>n zQL$#7^YX-QlwDMXh_KzEr5zTS`|N6CK|wtC`0QJ3*bw({vqk{P<4y>^KTAj{-4G!H zcDWg;a(c@cO4I+}OHIocagGl=Bm^T9<+I8+01vcPoKX)hP_~5gEIhD!&r#P@3B6zq zh9A3h*y)^Q#N36(_33*Jjr+k&wTtijU@)+W7MQ}0h+)j|g-nI+^Ll73Bh?G;dHx=m zW+8dClRjKDpwmOUrmeb^M30?!no)KDkA6OzV6?`{N6XPk-|yCEn8!ib7n%5590W4O zBjXH%Gb$R+A_=5O(Z8r%ue^zdv{aC0(S)EKR-j9z-X6{#BmkN?Iz%{@ohA#@c@M~(*CIW@2BVtVsGC~kFM6%nITHBsUK7}@-r&WbUBrR5>&rvkkO>qGpnriG z;wC{cO&8bP{5Xkt6#_KsLnYc2*2|@u?$m0i=%ofDa(cR&J_$IuJof;#TfUK~##)Yd zAaKr;pr)?P!R(m%!%_>Hy4yjS-1z_8N4@iNdu*UOp67|?ws%(qBRYKFQJ8`;Tk~FQ zJI9wY`d$bk*g3D03Dxssw4LxT9d81>`%cn;1grV(a-9DQ0y(>pMY4DAx(wTjrBvZe zZBqnkut&xmp`}15iT2RuKh0nGa=*i7R_h+rZs53Y@5XyW^Oyc!ke=mCY>4Rf*;nJ+ z>tHoPl53Dz}XUPRdSiOT> zjsNGUFwENuumxWmAi5@bR2JS2sXm1IY25Z31A^pBJe-FgX!>9(=qMt8u$*l~b&SsMId@Gr9Zg*hL zo^=(~t=^g(;LN9te#5z;BZyBQ1hj25>8h>KM`@M{ZpDc7x5dg>xW67)scDHl{&f2CWy?`6w*6&ZWu^5 z>NMrcnw$a2`FiqD|5*g5BECQ*zQ{BwBz)T|k#cq|Q_qO} zvQv-?GlSq({f14hw7s#qdTK>RaM`gyxEtrFsNWBb8W zG%-Am65me=Dw%1Vyo|N+@Q9B;?;V`&kBRX0fh0b1j+DXAaJ3N)V&dyF!W`PC->lfa zxB(t5cco?i#!xx{NOyO6;zf&_wfVOI)SbEbK}x)DPe~PdoR&quZM`GJE>e~wk4R6e z6zM${fcd95oE&+xTSj2lfzAbn+;~P*tdaCLH1P$09oFz`08gM&f}V2ndNrd2MkK3B zw~dB>5^_kNjR}S75!wdRn`wqrqTx>4S69wUex6M7(;H>xgwEjJ`;dxH#9{=6^ zo{@HxUhJwJ)4V-XjZf(yX^#hjq3aN@1duPpQ}&3iOhq;s+G9e-Py$H|{f!Jfyp~oV zZec#!lqs^c3hk0r_y0gq7JK z9OGtW`s$BGzaq);O@MwX@SzHsz-u$}z_@Uhb9}FJ!}=zSDrYrOw=Q;~0q(Qf6i>qX zrDu-+Lm_@U&oBMw(erF^N$hOUgZk|vxLGi(0{OJJ@3fI$Cuq!A&_KYSVPcEMaD0g& zM*09%8W`bjpR2U|Np(AYh&>QS=td%qkf)kOULQ3em`%bMZ-bax@|FSy?}}+VyFcZFjtHWr17G14%Bh9nlCB_6jl-b zPm4yv8^3}Op*S?kE=&?g63@vo<$CrJP28>WEr+^+(N!gDV@4BB22f;JkzDK`EvCX;Cc4~0rSX-i|1(CmlNU4 zxle|T4*Wjctf7U|n^NXTR8Ep-_uQo3!D9VWIr6`6*$s=U#0OpE^46pVx9I$eN}wp! zY8@bpj^-ynh@SxS)f%~ZY3`e>XRCtD?fDWg=36i+CG?j-_G1}3hB+Uf3YJ5sab zu$7o4eX&M-s_pqT5X^O7{hrT`06fal^l~*^iwtc9Z9sP@ofmQsYq{Pu{Erg5={x|b zu6CxO4j@dPJ9ouBIs^_)n~tX&+mkozY~WNH>}s7Y!zE9b zo3+XX?QNB=N2&z_JlKHXU;)5`x{i&XKCe*;p4dR6RAW~UwqrZ2<{kAVy4eJ?+~1c- zAY~%^?e5a zk!;PxJqbZ{z}9KOZzQK>H#0*Hk5<&3eJ7)6N?OOc{V6U-|2DY3iY#Q}aB?JzCf1ug z!@sRgmsSU)ioGF%9ua!at~ZMP3zR-UVOx?X+M}9T_0KALb7U3r+w#{R*NfDDBn zsG1UT<0%*e+pO?g$M-ig{tLz3DoQT&es{7qIEi~P1N_)tTozf#51NHXO3FDoOF9c5 zV~^|nDtG>lO13eD+_&W9_ADdRih~Q)qE~}e)KXIsVgvfH;w5AxK1nZQ{8(X4fwrmg zslK)LhR;VvrKJiPp|Sm;O*&kg8^N3w0|1fd6$NCfYL!$*P&%DeM__iw{~s#rzzW5m z@FG^<1rq&_ZCJ2mh%`pz^%6{T#%}!y9QpqU#1A#wb>lP1Wm}3Fkq&8*A>B6&S1mG! zi*DZ|Bb9Pnt?ntEP2&5W=of4;^}61cXJXy`%RK35N3ir^fWxf2aUA*u)_2OUx|vW8 ztwCcYY4BcCko1(?)j4txnD%^{k6ldgO)?x>0v-66J-`oJkQ}B&Nc^xw!a0-+!()=^ z{et2F7h#ub(IVPXF#h05Yo09_pgF!jXF(}WO|$d?xKcvm2nFq8aoTCpaedA#W+B1UiOpxDb~2n!m3*C zu(K0%WvYiVva7#u$v7ZPA03-x)~t)DgmUPdHU37xB5TJ|$b>h@ z0(KmiVwHdw;7(Wt4m-qx^)(G~k?yOrM7cV{6DB`@0rjM*@xY-!^OpowxsGhuP?7*Q zS%23CZ~sj#atE%YaLnO+kQ=z-+(6Gc{PRx(1ZTN)bLVNQ%R44>Z5YxQb8H z_|K_aSdHY=`9k4AGLUL60IyxJh%W8Y;y^Q6GqHQby=HLugZ5~w$_*gyVF#VFE6ela zcNQN+O{2mNhGpxgR64$}xgTgG{RH*5`DSHNOX&NZNvwTOraVdkxtf4>;O_b@h9%ZF zEY+C;={Lq{fwfImO&YxMHxT51U~MvAwjera#CzsdubU_?rM9%K_n91XcSD>3r-9}$ zn&%&Fst7Pz&!e-r5eqvnkwvEkfdd5cvD z*sU$xNvz{9qg-^|d{p;OC9+=R$SBUDXw}d4&wKDfS5tZa^wKui&=9MN#3i`hO2TOd z+;^mnP4*GzdAtWCBk)b)Ss+JmsbCHyc_01KUq+xTr>^$icEdLmR_3F_pU!eyZ3et* z8Z(++=*^8!Fxht4Kps?xv;Igx^X$ASC)R0Sek%Pbm%0LN4>zx5p)qO^fP9Vb2+Da@ ziKAsPg`l17?aQtMzu_qWRM8XU7ghApp_o8TtUQrro2c!B19}Y+2?pC$)l|IlF!N%A zv$T8?S`$$qh5Q{nU)da}9jf59GLY5F(B}EvFo}T^0Xr^UoC36I@})8Q_Vq{lVcwS3 zxvtW491qYt;3MF?yZIv8*_qF=;QQt(Uj*pR8)9>F^cZkge;#{Sa*~l-bG;KAvv|E7B23MT!@(& z+Wm_m^3L;sgt>uu2>ACC3l)P;&nF8T#9HR9L~+&P+gRYp&t9oa4vqaoghTfZT$+T> zVm8(-^rEkpa3|ZbDX}}#yf?L+wp!F>eq}|yPoD6EmVRoMttR=q*r>aNi5^CP3(s~K zH=MW-#QdFv@Vk|>pu<3zMqDOQ938GW!RmwwF(x2_wW~UKv$g5jcP?6O|81|M_ ze$cEp5O-ld#2V*=wlGRjJ~P}Lm<+d28fElbWcJA zUQoAe`fXwOt}R@Uz>BOBMi2gn<=<$lahV>q7>U3S5jW+~tdMrp-OFF1aIRNj9?EN8 zvJ_$%A)HROsK3tLn3reR@a8YCXBWg3(dK{*NTdl+KSK|-7dQWO^gb4GY;jBp;0c1K zZ;dB4!obmcAuIUZ!@lMtFhoudyKG_H?|Lvr#@DDA5}Fd|1-}*St<$qPB-ij~*3eDP zl^T+onjRbVI#N0_KT!OC9oSYh_8Xz;6a156B3Y^&JL36r*9VA6>4?2U8=Jp1T&(X> z{}!2rCE!u4UPr|z`zFjq#leZ{%M3^y{gl~;?K{zW6U68>f*DosLaHr?YFcEtaxA8( zqh@?*9eq*!qh7$LMYktF9+My9B^g{nCd=KaG5>F zn{*@&=db>n_+8-$$WX+TrXKmT>Ak3un-ih9rld5x4*+9UQ!K|n zf%~{+B2vCMa>%VW)feXD@M{BL8(OVru4e}o%FGkaZ{Ij!o4mt|CfY&Zy*fV!!OESW ze}SYFx-c);4t=bb(=GsONWRnHz5_*ft%(fk-6eTZ-YLN)zK&--;gQ&DbB9h?3dPz$ zjTD_W#K^lJa1>vhU2B{M1{h*%O`Dp+6~ae{HfuFRT+hB0#M>a$VJ({zLm9rZWy~uW z@WHm8_b`$RK9&uhVBTp$^6kgCrh~aH*ic}i@wxhm=(@Lu9ECYCjtia4S`d4 z;*@TR(HbYe0^i0D=R1WA8Qa6?+tO23>1#2+yrOSF=!-V61?BI(_uX1%N$zUos+s~ff^#9U}`ev+W1&FpI79A3+d=(8h)qQ)+W~IzL zeus&R@93xYm#R~~Op+Gx-$VxH<`GF#xC0h7!x9?iDe`_>tc>`UaWG;3hBV|XHuDmM zCKz#$I%gq)=y6E3(AvQ?)KlmW9vK)d|`s8Zi{FyrA&NGm}wn)^W>kh|RZEkIQcvSoiz(Fh0u0U0;+2V&Zp6ohG9~AuW0-fdMI? zT)o%HT+O)!56;1zUno) z;xrk)KV@N0ZB5Eo&(`YujDO6|zihRd^T?Y8;qxZ5lPLlUt~Rn)ihAvabgkdZG#0wy zTSoHVRcELJ3zvGxHU&HgBY0-dg#NXCYmIpB9b@R~j%|tMf4693Rd=zd#7PQ-OUC;0 z3QNxC-cw zosWLzud=(>f$q8xHaciIH&a)^?#ZlLG+-T|XLf1lsC+SX!NZ>&}z2IREl<(KNk7df~*Zck_ zK~W>(UOMTmgs8yI>z4$HJ&9FEBZBP2BQOcV#|~!5FkCSRI{xr9&ZSc5ckGtmk*ifO zW6tOm6}ij&K7SDt3CdGXO*Ptj!UrJ}GiT+Hn=+%?YDY`I5e@fbK(JE%y5AswJ9{vtuYWnj+y5t`xYB74XX@nyZ^o+dVG8QSz7F7@Ps@~1+gC?Mes(3tM zzgfv8#KJI978|4PJs>B7efb}YJ5s!z+Z)L=t5o*4#hlfdGe8ShgC><|F1bCwu^n8VEP2{u5z zDDYOS8Rr>Y2kc??o_%^4m?q`eqRB8a-meU!1!3$QtV9CQR)f049M`k zk4qsE$97jqc4kMCo#blQ7IXftUQ?-mUob&nWZV=76IuI%PC0-#e-X59e2NO_VA|9V zh!Fa$u??IgT3ma+;F#R>zzgBbI1A5b8}Mxy3TPg67YTq)JGWIh%#fHb-psgWNPFLB zMR{Zoi5qzpt?dN0@<$Ix>ok`l;aji!m_WBcIaF6FmkyCCGQai;68fFh-t2tmchZ~v zUY@D!3T;`D;HokMX;1DIrvJhZKe8IqfV7p8>#R7p#N()=(+%m=;*L%Ni&_R}3*T;< zpCrXTx1vl?5Ilw43bmpjZa>7sU%@JiYtx!5=)s zsw@{Df~V=yJPn{e)hdu-;Ncjy*V?e#bFjFT`DC56ElB7DW#dUd6~`~quf0R(aiCtk zy!=tiJa&0+jm@Uzkt zQMJx%sZZxiQ$dD0IG<5D8NG@mg=Hc~t~zgNe{fnpRr}3dB_C3HnAI66yy+C3_$^9( zGqUfI11k<{mZe(gR0Du~R&6wzH-zxM6ngESwbl`&Z-g($+(qGtU_$K}} zW1PKscW9!C)~04?z$F|O5R`R?wqVQ(D6=9buUTNtOhC4!EaUe>s|VqZ-s8mHFiPQ6 zV}z-m_LpKnp|4RHz1r*#Fzo*$E~F)fYO!+sxr>PIvg!!Mo+ywiP~!nz9$N|1GS#|M z55NNrCSji0J}IH$0(GLQR}QJ%1b3iZ=k}Klk&9U$IYUw+6p207OxMSQ2MJsEHiKbX z-$NyuZRUUA=EacN&KD6(oCuBQd6psC>dD`q$MX_Yhyzl8f&wS^r4l6U-p87yd%7uf zwqt=GxR3z%Xzi-`i##F(d;bxazWsYdG-^YlWP1Tt0gs?*XKx}#bx%>N1F8(cI@19z zHh3Tjj!EkAV|RK!z!EEn=HV&NH_51A@A6?Rp?AIY4mwt>CM5ZYYZz-SMyo)U2fJwq z^Iq5p3EbSYASbJS49CQv+T2TRpr+7$_FZdsX=7Z)WzIK&-i_pzms6pr;!UO{(|NRO zUIS8d8uGksbmVFa-^Rp|XcD#VQje+T4sI6@78|Ew0jX?EknHvb5pouB{{}DT7W+iu zXtu{;PFZr*+FjB;_f$!XtVhc&DfB`j39rLI9z*24_@&G`&YDT9TGIFY;A&}4X@(MX&>MQzU=IWO1p83KB^i*tAXj9whXzb`|Yr5YDIZK1Gc(MJG zo<2ga)aFF@x828CS_kJx$xj1sBb#jcYu-fi@o-jHSxT`x3>59~%Lijhf?%zU;NMhh z0dc)P^6V{w&wDcsy=^VxInRYY?jKyZeT!}RE`Z`!zc!wV1YNjA!Jz|t8iw>-1d592bM}fd9Ha53FO|i=x z5By5V4dcrJ)Q-|P0P3~X z$#OTl(d(do68xtAz*_+k49+jD1$m(DN^=w6UJ?+`J-(A5C8c=@czxEf=AA6cgl>gN zg1yW@IXMjN+En-mjDRi#o63c@&vIy;_D#Jji^A9_%W~q*r1)2DkUz ze4wqh1V29!TpBahN0Qk>C}jMGHmyhN$^ENxaJo2!ZePSxRCnme0_JmAlnj>8b zBqI7Cd~mn8#+c!$`!<6QJ_UPHWpcXD4bEI;`9C zCDXt^77%Q_I>eCO&dUa5eoB-QUVox;pK2h6aP9JlZa>!^$S)Yi9nremJP@upXMM z=Y!gyh1BuB3$sC;hwWsW`;$n#7~7WFW=0~0IfjeB*rCQ$JW zA;Hy%MDg-}YiJh|2s=o2Suw=c-PaBJ9YwO!B!D1&qrWbs3~h}yUB1D4!!eHiz#Lla zMA56;lc*F}g8U^XpxacoMm0sLDJ2QSJ1Zso`s0w=aN_^`1ixZ5u?}&RiC2 zt*PmNg9M_L*y2O%5h{v62oPK+I$95C=Euc7IXRpQMtVa21_(4~=(M1a(s#P)`Urc8 zo2R_AQ9A5$^tPktqzL7?Nh^NthHmG;NKv<@$(74#bv8~e{~S}TI@ zhzJ-u2!0vO_2^>AflFCV0W_~|-k0kN{N^=nY{!I`6$A^eA*4Cp;sn*TD8_|Jx*Hk9 zERJzn6*-#zM)R9vL&P$+D;Sk_q)IATznt?8&P!D0FZk)iW@Fh)J9xX%0_}O<2ew6Y zj%Fq9Ip!m8s5qOXsVe@Usor0L-16vM6UDJ>ovwXXqgsLr{Ew&fJd}?xwgmad<5hY_q6{5CyV=Mrt7|HD3no2d zgWOwhgs5qu1t6;3rwhSZfEe$bmUzUz|8Fl7IT_GDza@-f9&948XEqHNcuoceuMG?7 z^BNQVLGpZ^se5{9N2*WfU;~BthH2PnRp@jL{~cmups8QNwEAnMsyi?x()1iZO_hdq zKh~^VAeGULLcxn`#XWBl#iHOh?u5_r-Q<=^=)r26nEa&Q!0dA8Gpz!_bQ$m(Wv{zp z>_3+u*GUV{8sI*r$van8)(@tEAHgGh`>_q*CEW#S~=3zxEN^S3%8~kmx!o zE;W$pW~@S*GMZ|${#sZG9|PvY4VI@Ky5Nkv#x$xX}v}v(YFd*=0=?;o4tLd|Jm$yQJj81Ey!iLo2@>nZOea9&xQ@1S1yV)i(c2-@buiOV_e;)siAs zx>QzLXp!P|17Y)wo^zGu**b<+9E&H#DAtvpJ9;=lVBeOp&;kiL0B zNiRo=z{kCcJd`GDUMbbb$MY!d_We5JW$Eq9j?xl3$qkw-ng{xJmW*Ytv()GY?)OBK zcTi^U#y49ASdn+S_P6O_Sk=t{c+BKxVqCS#sY_d3vN@p`(U}`9KjeCIhZ)(U%$p{l zVbc%R&%;(UC9kVV^N1D;SgXZgx0vwymdAp2gt_Z)jIlYg(l792Ngd|(CxGGvNUbnJ zm0zdQk>Sww3uc$`=?O4f`1gxIM1H*~1K;8**dft#UT+xv*xT$r$Ib=K%7fPzKQ;Wu z$nGwsYggb~m#52)bh~agt2kV9wX988m<(@CVJIVauiiyT2^~bDM4Q@O#({;1;%**Y zwBncn<~LShQ>eu;fLT+XmzI7-AtDL#gB`-3QN=V*=~Hd%2j;LI!!S#-Ax$;1G@+w( zzr_-j8hul4e<@4XA=Oy9As$#`XjSUAaH`UzqSwPwr_QN-F~)b)&kK&S7AP#!49!#0 z_s7AbLueiDg29?K?Kd7U-z!_lt4_?umFPl#%BcE&WvJpm*)bqWWzlq5P)Fs{L#FJC zVXT+Zh3vSx5ZC`#u*ed4A}wX=YA9Ro|B041Ja>#5>Gy$81wmBwTMNh#plfy&8rAV8 zYMMjCFMDZ{vVsZMd;wJKwVNM1Copx5Q#}#sS@rcZ^@OlKiyJ$NkVz~ByA>!$Hmx&q z9V-Y#3`1XYQ|$hib3)a%>1`JwV#V;S>ll-H z7(LwNedjY-eMSEhM19vemy7=&SHohuH*cd2(Ys1bcy|i%6xkUW<V~E<2CR?-NJr#jJBkGM7bJdSFdS+CmM&5Iz?7Z6(PoA_`6>9jd zf!0rlil9i|>G>;qHrcL{Vzi)3!H-JB8OsvhPd!~SzW?)GT;NlCdxL|qz_`SWu(yWQFhQT+;;PJc~;Pt)TgeLyOH4>~txs#Q6`dpf4rE zw6^Y$=4Gg_!9y1$qYcSvMZ1~naYWkNc|$;~lnA5x6{C z1H}F*KT9ndM%#VYDy#+A0n4+EKBB0Nt6e;n?qJ*0jY$nR;>iqPeX0gQeF$gpKul^O zayO9s7T zJdyU;3QNtK_({83r81K$*PWirm|L!ny+RGP8LgQ)j^Wpjp{c_1{TqooNA2th0Wd26 z0PN*__itO2#Pj0K4|6JCiA?q_%jbg_+~s@|Xk zUFLQUW|3vFze7JtxK&FNYZhz9ykx!9unPY@W>C(0QRo;49$x21cx( z{Td87;WV^JT_^7p^ka;JsA3cYI@^h1 z!kf+0Wt>DO^xTIWEaOfj%?=wx_Syqe)1o&qQL>sCmxkx~m8d}&*hK(#O6O@f{fFHr zbcM@n{(6tssO-3Mk**O8Pq`M(eORnzmDc8$$F+B_7XcPWHk(0?h9Hs|NmiIs?ht+j zeyjl3^EyCwcQqkGV&Q}NHdKFtR&(fF$B#_PNdHjq#4K4R*4roGe*yMhG-6Eus`q4{ z`u@W8Bv1FSYUL({4?z?J@Q@dT=a8Rb1MZV(T+X0t*XKwp@|6(@3e7A+?>LAlPhj`a zg~>s)@0k#mIZD(e?A)}OQ1JS;W^djY%-rKv^$nV)zxU);RAgvUcHhEw_&SCE@V z0DJlO7oOx#~i2hV&T(~`5swALlI%7Zb0>aq@Jk?m59Z`e#O?eKUjT;18&)^ zD>rP$D4Q*f4Y*;Zg%_*%>_cHW8EROm3Gz=ll}M$M>Ljat)?28)%e%e^1CMV=wR5JD zi@gB|_5hBIInEp5)Ro9tuNvaiVd#S4lmLKb~ndH8cipOSJlCwomIZSy0Qw zWtA$$L?mCv_ftf3;JwR14;3he!|bB#G{Q!W(c?o|Bej+tNksr1+st4J42;L`c(dDi5y-Z3Kg3RVo z-BnE}3k|EJv_g^~LL>Eq)u~=O})rSf4QLso_ z)SRSkyV9x*fa^zRGgWx1(z$P5EqX;$^dng${6P~&y0S()rD+#Ti|=cKqy)fRAFY8n`G4+TP8LFVh?&E&wl?w#i0sQ zqpw6qBtl`h=<;IGgDbV$BoKi3B$wEsY28Qqp|jtC>6BG50?Apv3% z6Ak;fOsir~PlMt$N0{i5zb7I8EYfIM*}MEX44V?EQ)bb{*!@Kj4mS~Q3?*mYcXcH% z=r!d%a`B{I-}jiOJgB|jJUoG!CK3YG{P`lPZTyq}Hw2{-kZGs>TzW8r90a!n1NW^z_`$h>LEUn;ds_pLM8F(&IuE1lVFj6*1Wu0m7!D z17=ddmzlQ*mVSoVTgbZ>W8o1qLt91~)Enj7#Wu?FfuaG*Yx(PYiDbe1bs_f>pP0E5 zg&y<&!>SvoVRsdm9dF*6EuV50B$t&3#NFW4wF}0}Dd4|By=o9%plc7-A+ynn8HvWy z2UlV(5Ti?BtrIFT?=FJHdvS4Zqb>~83Pd6|3CRbbvUomQcsjGyMa#A$?W?(F20Lo| zIO(RS)47D&Fc>l94lz_}h*91@*Jdf!Pt z;UN)qe37@p=n%l%L_RF=?=38;d^m6ASoHA1Hrd~hYZ6duRBt*1m*HIS_Q9G%FPU)dPOfAqU^j*0uk=q(3=}eA~ZE?Lj1F41ntHcjtjG zAfwneoS?RtP3-c*u(K7o_3jnHc71x*A)U+(KsE6h4`g%M%h(L8Eukd49W()wWQm4J z_)sf4!It+jyT+P(sgz>DD$Ww9JRJ`HR&s1ycL2;gk#+h3v3ex<_nD5?kr&vfi;qO3!5|AkoGDIj|cCm-s@P8bg(7PYFHNY^* ze<<3Cui*9J5^JacWe1hy+&v0md;HZZf?Nn-Cg1VTH1nx(91H(Xd-aG_9|&B%#0GWDktV$0%iLKI5L%OZiCzj<7gchYhi{4H9A+o;;bSB1axExq&AxY*t zj18aRTsrSY&(ln219m-i``m4?(JQB-3g(7Nu9m=UkY@Q&h?-{^r^$ekjzezqJ5?IV zjHZ73&kQdl=?OHYa{^~t3_E42^pMzOJB`*q_vC`nLX5#>iKa3C-WwA7&CVH>4EnVh zHkIX#yVLQ1QN>xLh9`O}#3^fX;%pB~lFq1?(p6daT_Fv74Ly|t_2eGJ=XPtg)OWJK z-=tmUnf4=y#hXV<#iQmOSgM7Sa$K*McR71-JXb1~G@z{acy$UjMi22WbN^>vzzNZn zF~}jkJVfG=-S&k`pkShVdwko{e10Qy*A{H(u8}xTZ|LQXTV}NiSKc_eE)Ib(?|qUN zklfLp^syT^Nxf~UWAZklA4D@b!}NRxVQ#%>&c_ASafjql#yF8krv(oY7CQ>*_TQ6F zc}!d>3IetXCngf z&qz-V3+*cl6~X3osu%=V-UevHJR02%Enr=62HJUFv1LMW=&g0Y4JOb=tk%r z+G+dVM;9stsXzegXN}{#3sxZ*7?Y$iyu|9rOgSalk&})#oYre=jMIh$B10aS)2tC- z`$M;S*g(%bj?ztf5HMxp;!TUN@T%KP%BdH`q@cC3_vCIGJKqgxDBR$QCcS?&YuXcd zrWobrPom-sdvw+5;Cx5-?o|$i$d)o$B*8>uVj%HV*2NAQN$nPb8~OehtLwk;z#?@6 z_Hn6xE&h7j=47^p7qD37E;?R5&o|oykxb7%Io0NpN4v}P-jmHaIIeU&C!#1^6 zHa~7fV+BtRO>~n#8f=4qbZIvFcn>L$#=#vr&+D>T5=>U3RIK=3MP}v(Z=;wZv3E3_ zE^A+=Tlw}Yxtja$k;woSw>dp2WfyQJrm&sbv=%i{h;lM-9Ys5sm}A?~=H^ISd&>Sx z!y7{NgVsAG$oNJxG&PLC{YuGti>G=iXEM&TLf?{>RVCB2xh}9_vw-{@ocv>h;@(fl zxg<&S*&x0-Laf6@UFeG~71P!GE9W*Vl3Stp5 zJQIJ-nO*tlYG~No!QX$UY0D|0wD6-cmDKNul1-Tj#lu|+UEeD><*cK^fCSrf6FdX< zrICvr73=VuSx~J)nk37*-x_6A5t5tN*p|b;=m^QEMwFVTIVqE%yc0>B*66#2vN7=- z@)L}AoD$HaS(C-)rMUk@*_mRgqXF?+knazfuT~pIUeY_35;5eHtZQ2q6oth%Wf;Ip zE_)(V=xFx9^tbaB&8cM!osuLi+cExRRiyfosXYFytvU2c7)lE$xY5{`18PvCysBt5q50<2ZM5AM%{D` zH_4n$6nx)_b)Q=?YDE8X+E^V>yakyh zTk@>~^8x|xz$cGFA?ZGlF{z(Jp`HmI9aH|@(Vm;)=&f~&_6eOtDfPDBexcrr8pOY0i@ zv(jA^D?xJK;}`ehZj&S!0)h-k8smiJLio@D`@dXzpDos^&G{H9WP_Wkf6SDQpEl7k zGb=jXW1_Hm4T-~CkHEeYIyY>D#ow9svuH^i9)(pP!pAp60PI~NC4F&1<^8Y3T}qsK zOs30CWDc9nQ)-zo)`h@)iQ*C}@&JBgVksqQhg-3mX9oKkSkID3;6hUTDQs3liiD0U zNeA5=n500FC@2j6lseKDk&_WE=hM#+LLa*+#?tWHbg7H7=cHqVO-OfXI)f!ci0pL{*ZxwvB8@h|De6Do0D?!e@9G{Z?LvoRs$RSi zf~)K=3s1-D?J0@Qn12z_el*~hhUOp=PV?y&?NC7H2sO<_6~Xg7DortG%?S+haNMoF zoJ-A)Jhvwb4tawi_whPTdB4AhgiygXB0314&-Yq+(cdivHsJHSj`2$n07tDUz6oEs zF8{gCjI@dfy8V*1gq5y>uzv<5u}8IbZNOy@8>!DW2zXH4KQXe3$az0a$;k$+3L`5A z{Xbli=0T)rU-ZHuyD$nK(o`}{e!#{xB%86rKkRCTW~3ruV+T76?DO>sVpdey(GFrf zcMJ+(?OokFzINh2v%9+c$=$0nVj8Wus^#e--ER0MO38ATc`sr~)+Eymp=I~PwqV_G zJBn!a#29si+5kZr#CZ?%y~Y&5E#SEVF)h|(fcLE-7;W97P8=D>{EXi(B34Gt^@w}G zSwNOp{V!dWE)}~qX_@84xA?8)9{o0faU-6C5yS!JVYYc6aptx`3ho?pw8%r(^4Xhcls=2&usR zvQMB(8SV%31|s&Me<-c1evBI&Ou&t-uCQX)UMo^2WhY3M%sZ(5+981h-peedvW?DP z?Ne-^a*#~4eIu7Vk&-e%8PuRUpIj?{crtO;qnUtVXhXvwLoqk_n$+d7&XVh0(pyh3`Qg4v4OOGxudWPX z_o{vrzRpb~%#+)rzY)8+(vc&Qs@2M~;)mQFsG7~Q7Ak$$k>z(CqG@C==bwp4G=%bf zlXC+gLIF`g`dGH0@8J{wnv<+B&4;k;Gx2UP>HavYU6}2K{rZYnI_Hp;J#EZxuK;?= zKv;sd;Ro!-gA7FlNqOgGqG$jTA2)q5zS-x&LsWfJjj7*de{`MpjwH$6ZkVdn8}RSq zowF&N-WPq`JI|33kCVwKq;5CBUchl{HOmo}H4!QWf0#TOPyh{kxbpJe4ap_U0mJ-= zHcQFzOR)6<9#ZvMRb~^*xqBXTjANyzwHwpkFO_OYwQp(db zUH#A6S{_a#pQo+=6#1Nj6epzcu|L8(yF+z8iN@KVpl|8Lv#9R&bc%>o<|R(10sBeu zXRiu@f?kL62ooKqWN+Ki*ysN1KJOQ_LMlhANg6GtlVCj zm(Vtj{ugYK?O+r$0zck4O2g9SHfC@ckmC3o#RB5sO?68$4)jK4?j;rk>j+ZnQ6238 z+m`V3oMB$!c7OGF!nV=`q8W3mS0uSKfIW%z%>+v24*cIVl3wkuUIvea z1l$4kT7D*R)v9^0k(Q{m**y>l09`WT-)C44b$6JxD{RN11*id|LL(lLi;dA!2xuR1 z0m@K=S)Dvf)`w&{iR(U?WG?V9@|`ZDP^Ik6t1uP`CeY42eknwrb7P}PaPB^Qk$=ue z3C7;3)YL)^`y^X-oVP&2MfDY)P`~-H7aTW->n<>XcTUkJ5u#bxFO5J}8JWyF&T8}x zNzwYZ+Fak!Zc=I-ntqyd&ZiS=-UpAiyD&oa_h3k~7+C3}yqetn&N-U?sD$rFMdlx< zQMjR9mP(aWmxNH~+7kgF4Ct7;jT85d$@rgJA4)#U_RfphfB@K9WO-6|n4q>{Vm-Ht zw~H;PqqFvTaUA@XBVTMq)ywn*}EbAqev zWIqnl)B%A0)Y26 zk-M`7ld$QszU(S=b(*Rb@ z4|SVYD?S30G4{FwNW*4OD zB-I;`+u2N#+8KwuYF2bp-6%*mUVF^60|j{l26|`>Ia4b?MJofKjx_N=^TEkp1~`vE zVCS1JpZJhnsaItq*M32@qGjD!?n}V8!jZfi3S)~lR+7UllK#0ndSbphi8{>RKm7h| zay7JDrFGFKYqQN?rB+!ULz`>2vQ5c9Gd`4ZPG&vKw)|#7GiVJtzDB%+t>mr$`hTso zq$1_r8Bj8lVY>QAr=lFj|4w^gwHvuNglnjEZSsd%xM}fyK))nv5wa*3@8SB07o_8? zqT}w4@gCRe^+v=S!F4!EP^49vYp8(9y12RPemh30;6eZWd(d|X>TSjI0;)7*t+!K) z;GLDCAg-!+iI}}>3$W3s7iQ+j?Jozh?8W}Sm^cz5(1&R$Mu|K9%W9suxZMQba*M_^ zK-_bgPK%yHIypoK)aDX(ybL5%8_GjRJ+(?i3K?7X2fVF1Kv!Pk_|3J(#6ar?aK);C z5Jx9+SLwz6P9BWqVP7D_u%H~uS`HDq6)WjH$b4)WaF$PTz}2%t29Uht5l?GIXy-T4gME(m1J^qj3E6q+^>>GgQqnG`g#6gD|QeeRoS)H zTC_ZqT&1*LE3pcSCw#V7KBfHS*XlrgT)7T2z46WVAK~0ezJG1V*sF09rWF)X*~nHM zcYEEM8-b+-Ug3Yh8>l%Kb;E_yOV+X72P(E_t*qDn5%=eCq$8vdJ|KLU5+qpeFNb+fJf>ob!+B4(~>L4T@zyjm1 zcWouPK@~Kc%!UgBBOi{-HOl}}LH3ry@$AR^DV9YAX@!X^x4UDE=B}G0V4jN;+$C0& zo+cUU3pcwgcmf>x_6{kz!CI*H1clfpz_{LqGb>e7fxD;mmgRQ@b|lb0y4d5e`;*)w z^hR{c&4U@naIbQ?Y2xS^I-K7mXY9YybrYS8NKu3E9rHJ7(iR7I0yYxzJ(qznmUjCU z_6?yZ1S>wFnK7Q;bkmTIyjiE5Nk&f7|Ndx6`R&oDtZoc}fO&EWUydl-HVf{gNAtZn zc+8Q6^|Cf8S)&eEwslBi)RwAf>zG9hRR`Lqg)UVCW>fw}OJ!Kn8;zNf%dQ;@o^nM_mrrJbmmTpw%{kY!sMV*F`E9)=mTvED9x>Ne;3Mtc$iV~ z;mWz^^p%UV9hVZ4L11T`K0!><<<%Uy3U<| z;yv>#VE}YMG0735L>X!O`;n274F@U&5=5_j#L!LKIcSfhD-GErfh@lb$BfUmSuWy7 zo@psm5C)>*PuZK_P`jC~YVcDYqW0(+gtzFSNe4z-#Y9($1+Z$x=s^Zs$_0y*!H6A* zmhs_Dye`GNdr6Ag#{cV~FH!m+h*`{lSUzid>gc0};QpJvw3?p5_Ebwjq2}nxN|2)I zRxczD;K;0h?xvTJW0sq4vcX_Jf4-$zn)Y~Tb2OeFk+dOo6@?lEM1vVEt@z#9)Tl3q zG?p+8B4_s7kCJw45Uks0`M=_Qn2$Rrn;Gz60#Qw_*` zrxQm;u}L7f1q|5rvbSaVe1S8uljik^T$tFctauagZ1#@e>Bf0>6SmAuCLQc90^$SP zK8-s4z}2-8XKIP!SgnS;?TTx6XN?>4;=Kz$#-fFO;$}QqRsad66#YJER)jkAV%|aK)v7n0=v%y~wG-8O^w$MDu zIi#E(*g8Kl15Y^;5_D+C;v_iJ|_!~ zg&oA(=qd2Ak}-Pxiq^=W!9?Ph8hE#W%UM*wmhlZxYOu2v2xVyg>%E!Jq0S02w?9fb zhKWCA7c~$$IVrEt&rtObl*UB@YN58xAlem{HRg!y<_*hgFXAUs_n9j+fDU$?>R6=E ztxapQT}w>nM9h?_W2A zJ93{v*g`rE7!{?-q!y%}7;!5yTZ4BJxv2H!La~HyEE6^n&fOI3n)uf~1)iJCwseKL&D)pXZ;FeRCu$YU+2R^d^hGbc1I3f)<%BjR8> z2rvI5ZnNL}CL^}>8h>)QIRrUG#9HncXR=H23|7KRLmA^6BDnBZBKy2ChbvbX;f+*I zd>rH@-J?HqAo!c-4q;0B1HP{(Pkz83*GRm83nHFLeEFN=JjQRA-J4+X$r1@655r9a zaLae47*+gm%!Xwq4RVX_J6gZirI=4g1rKwvAk2NjEl8FFUZP?7y8wDAlnDZRD3 zFiRe*kqlG~7{NJ3!%{uNK_b2_|yJ5uEXxq-*w(2`LP)1U$^wF1N zowJ?F8v519b>p7(-kC~Sd?;=xSDinRz;u630OkU1jZGq*V0KtJqOX++U{*x=qh!)= zTfXHT{lR6-njU|rAz}B>ox0onxZcYiSQN6jR1cd=H29J@1t$nv{a?EYHje!Svg}x1uiO8NYXJ zSz8gEnS8bVCVl`4rB~~JzjB@5M>wX&BEs~qLLNI*hM2#_s#+Rywz^PT<)FVf&LI|^ zbl456iKq60c->PCT9hCAxJ&z#ZbZtnTeq-fYeAT-+xQK$tJ}Fk6~U9@mP`qfr4839 znFq%)V#a{~f0T+pXvU%Ma<`+0n4OBY$s= z`E~YmHMb5dwG@0c>b2?Xt;lSc4>Y$u*lN)3O-h1^Z2|g*kMyz$zYnd2b7{;j>EP#K z6^OnbKF$88Z~``7hmcgUl3}wczCv%<_sXJYcdbCTIl&o2#bd0;4R-v24fWMF@uds?C z=NX_Z&V9MfJ-oE8$?cwL@jJP*EuEjeFC9cF4m)Uj-prjW{^EGb{M<9CC z5;BR7TsaLZ6WEZcP7qls*`$E`UI&ieyzTyHtZL#>$jRO2we)$-`2zb=&@X>}M!Ys2 z@1mDE6hV@RHi<~(wT%Q zkguFq01Is;RY($1`?HPd5!6EoJ~DltXy4@xW!9Lg;wBP(mB@htXmhhuG&nL}$wMo( zlvS1@F;>d!Y#w>5i{!K_Q*T#7RpMfWA!sCraD1;xCL5C-`+*I^7xil}n*~BB)v=s+ zOKQZ_0?02>q?~&k=kOL(ibIhTs9(|0jCiq;&VZ#hs-N0M(&i+=`FaH1*rw^joKF?| z8q$s|j#8)gF6+BPnU5t!c!n?hg$j<=3vtfaOp*g=D4yDV{q?IDw7)N8pZ-mL9x+PG zc~b?$;j-*jV|J--^ytq@HpqB%Bwhr=WgJk%=W_@Ua9~m-#9s2<6vj)`(5u#^gV#sT zKuT0H*Du8+8KBP(Qp(spFwBfTObLoNNYk149ZXLK_$13|5p{w%TneZj7Tur`YO2={ldZ3r z2i}|O96!EKRXTe0sMFS8M0#uzUVT|X@QUc3dGISM6Cu22CttDXi;pY?Em(O;*wQ*Bn6EvP`KGRSO)QWAPkB7 zYjm%ddL~jO!Zpi9^6Fq6wrsbf^#nW*SY})F=4u%wdAo&pr&Wb6BFyum5E%n6hti1M zA*gB6I-L<30p8iP;;K2Ay`Kyf3)m&&yoZ-EkfCHlY0tvbD7xNs=O8KDe(_~wEJ#^T}pONAGP4dcWGuQEkHCMNfmEg{F8QQwYUF%3_xs{4Aj-RrJ3iD^T zPA1pfj;e1(q)wTD0#=>z`}Ii-jj5>*l9YuOW08 zTyDQ&~eTXa}i>LA0kfuwNqyJVAZLA%8k>?LQu= zSX*e>e6wc9dnbsR-xZ0T9#eISRnG%83$1JW)H%y|SbpGqu(e+XLDirGVv7}vbW*yK zz)B&E+WvzCvIUGB&ux$IT-Lj}g33Q*xH#7L-U<7HB}o0LNz=zLu3<-^?g-i*%rv`U z8``RID3^ny-VFn&3cd7goo&Zf6pFf@5#`O`vP>bbfPmSSkAR7p96mzQeYZRJIi&g% z@POmfCwQ2e%wwR*V+y0bCDL@V+W_S35;5?9LDO#UEKt8LGDRV0;-{<-m-iK!D~+`d z3QrDtyR#^E4KEQwzr!hO5g`E zkINIq8}XiM4&%@(rLKPmxk*bADDOYgqOL&x^fV!14+auEgxn~+y8ze8uTZ=y6RX>> zxY$fu+O;Tc025KxbH3vKM;ReFsPBsC0Cnyj4JEoE{n$H3hV2@$1>-fXaYuaF)CPQT zw&%IE#52$ypiXq+0Q2@BsKf(~0Mt4w8eCXP-oXm=J<|ttxqM2Q{n0n$Vo-S@mhG_i z99nfTPXAmWyReIr#zb z-NkYOO@H_3Vd_{sT$SuGzV9}4(^ILF$pWV?R?fyh?K-ofak>aUfFKer) zv2}s$!Q>TiA~Pee-^5WLDexi$E?sNIktg2VWsW{^eKu8tf$F zcb{-)d7iTW^H34;MYFXT+72NgylfTw5AE`T#Jf7f*#c4K%OLr0)a7ri1+>Pg)}leY z!rAtk*i4Q?wg0uHzR`1Q=__;X(81=2O@@?&8s%{1FG}r-Hg+s{=e@~o27XTnAt7bW zV+$UhgX5sKx|3iJ*UHRPZ8}0=$neBuC*+}8+{vGH*Uu6f`o14G($2=5d;gT^t<@Sh*XV2JW989&@W#`VMpDxq9S$#YD zggf&;;duBvtsBov>0ZEs?eHeO$sGnE!m(8^03+>{mLd2Cv}y6cjlj`>wqF(!48^;9p|!JR`c!|EU%o=W~ zVz$H6EpOyR(Xe-)*|M$3sQZ`SJnY}JN}TN?!NRigmoyf1o3nLrP$Qs1nwNcdE{dff z4~QT0wbF`wn}+C(8@X{Qa7mHhwlZ$5GWRIxi%bg=JV1Q*{gf0>}KH@WokPsdm>l6z@yGQs=^Y&4OXElXgPfftM5`Chcg4wso32!|xtGxZaUc>h6DtOwt!(lRi zX5DNTVFPjM)_)k}UKGJ)V2z5`cd#8;Sr!BL0y4bxsWM#TQ5*7(oj$iqD!0*pJymQG7naep(;6g*k~eyFDs9E>?#n> z_66hBW>2YY_(~;%=0o7ar4`LyTyJpo-`}3N&;sMHxRj1lLxNPl{&|^&`p8sx&7H>s z1MI2sY|Qgn=MF-&J$mxoL}|oCAY8X`dE=Mjtk6dl4%*C9>d?p=VT~&7AQ#VMygZ2)?6KUW|V$OJYqqh zt%b2)|7=fGnEsaz)P*CCxv^2X@a>YeuNj6@yEHk`QIL^!)_G8CcTHl#5sc;+ruQdG0Z9X9S<8zJ^(9V6aJ zsgmUmn$~`fi$R5&PL2=800cCNe--j6aE)reg%kMRO8!!&LdhcgDhyhJDj#GY#*^zk z`^Br_2rc~cmPO=q^Zq8-(xacOST?sj?4`ztlNO|Noph47&5dd}T98%@AxtKA$+%B= z#l-@f#Sqo96)+}KtpWuNIx!PwuBf7)C`g#K+nZihgWS%qEP^0n+^XsE?56cGq`*Q>Q%|Ehk6Ai@yirb+CoD*mokVaqjA{LmXZd?u$iW8kKL1I$J_6z%Rc zw&9vYHTRX-&@PmeSYu%na_%z2NhE?LWx)=?NXGvN7G&qW6l8HBQO2bjDM4|P@qE@k5o%u3x6i&tI#v4srH{T{W z^!4C%MgofS8zfwu{EiV16KM?8(bK_63(w@)Yl56f6sQ$aHPYr{b~1r>P+@p<{`(s# z+ZSYT@pQYv6Zo(EX3EBBoK}dM>cm&Rwl@}ZY|5@DQTU&BXqbb|?dXGytV=zfIXngJ zGp4~uQV?yKc=r9>3Z!#7oBiV0)x5f$>znM(g^y)WtQRr|n5dApKWC@=WO3j`T2b#_ zpM~&z-Q7E>f{iadlzisxm4uoT7rOhfe+Dp<}cN4*T~ z+DNuNB@~SUk4Rt#Sa%}otPy;VAK=8MV%SULurFposN$|qtBpsU(TEQbZQ$5?b8YH( zf9T~q)8Iyipz+k?14EgQVEY`Ub2zkA8_ZeqVTxpq;aqBe0}xNxFf)|_6ANOHYgVJ@ z?DS?L$?6A%dfmm%BoQEjmdgv zK)g^<+XPwDcG-V4u@KFzRRZe6HN<2nQdOivo3U0^bYVP7P^F($e8YCv3@}ra3Hcz~ zPts9?@4H@HeKp$a4{MFvO1+Y?%2JC*NuPO&^;vZaL&34x$z#M4M#K)`hq6xtp|D)o z(Yg$nk*;b1^cn}@2A|}90k4pBC`l*kubI-A?OKIF&{qY#^?4tc#E7R+dgC4pta*Gq z|6&?MOaj1zC9>d@z=ih{@O}z55h$2TObryd?Yn=EXaEUZ!|3@Au+UK4=P%a;bxTBK zP7sy*!UXIXpR$bz%wR%UfPo3h0dgw8)s_@5_D529)%~s`^d_AuRkewm_SX!W)jegX z3MT3Qffat;yK&C!==iJ)-%sXBZd&Nm|{+(PH(QJW2!Yfa93 zx$z~8cLY}>Y0r4)aZO0RG4~;P1lUpTY<}I)M1*DDrWriN9nB6F$R`I+oKj8sq1w_t zpMJ5jL;bGsXSvyjh0;yOeVy3EaEt8$|7C}#FPCzT{$%D_zQ4w;xthkFuWS22=g+aD zWbcq~_4N~9s8#5Jx;LpCpQ;dKD-vN*{&fOonGkmubebQowu;Nnxaf(pZCPTM?rcZD z(1TlICxrFKyF{S4gblJh8K9UAWt`$I9(}4pX5&#i@)@a6rbTH5HJ+iqqy7T^)BNs) z3k{#z>LO@Evu+Znj&-V~^T~u6yog0KY3Yv1;wGIUwZFReA!PHlMpninw2+ml2NYt- z$8kQFAUygS$TDQmQoJ0v$k~6iM6^)2d-tP-Gji+AUi0=s)rQz{)LhvEiY zG`SK8E5{JYwo(w(JtzZCRJ5jFe?=s?F8lBo=-a_t*&_p?L%?!LBs+_*CYJRYnM*|n zvBCVib1^>W2dt^xqkDACWgi=?+uvSy2m9QX=d$%+k1axpOO$_?oR~##6Z(0a-+Zpy`x(*ERn+xm&_XZxbW!IE->c%;4Z(!&P zXqBUW7ojN2!B%Gd?LKG%`%Pz9o+drPYUCi@L5Wb%49PIgep38!p2JMUJ!QOSeInp= znU8tp#2v*qM9d`ekWbX(X0A!6l5MTg)D8xakM|#iD5cubd6Hmg0c5vN{J~A2O*2)Q zbLqlJ$MtEYWZMF%XBqJW2=qcx%-o9lZCct&w|YgZbyM|ZQ@mMsJZljzMN{5~oGreYWxj zsKnr?^`6YIriL{0%CYAHZfpj*NS9k(`h|<}=cK0qO%T%%f5C*R=OQB?jiTd?pa%41 zd7TX*7MKBZuAA(h$6~k&^7dpHIBByOGz5BJ&zX)BR-JH^JT?eqvoyx+b&Pnao%s|U z5^=$EO>kCpK|%5LVr*$9$o8k4;WK2utpt{_=Y*>xT?*OQC%_D_kW&PVw)la4eUlU@ z&apsd?5(8-dj^Q{s6@8DUarq0&rFG8R>{Ec!(9;nIALUu!Zz-r>_a%A7=knnyqP9! zBq&*dEOX>rJp}<*VU1P-Iqy`2O%QBV9iw>i;f&CT9Kn4klxtYy)xo7E_r*2MiIY4P z=ChIQ)HAq!*-rSkkmh-o^`qC%A7+?4Nn-H0l|{nn{Nd^i`Bg{i}_5=9W%QQLME=IWI}x^Lk4@L zVJy+6ZTPa9Tt39YpsIu?a7oFP&1g_E9Og65uvb%`Y8bVCEus-M!|0%ibg2En?J&(7>GgpZ4|AUYd!4DR zU=U@F-Pt_F?PoY1(qSrexW%a;+!aI0hxO%fJs7^iF$u6m)X0OB8#?s^!#*HO0~#0= zAk-Z_h^A!aoRg~K&$H$ZCBf59^wBX%?;>|jUH&qi>mg$P#+A4UMH0k-^0$;)SpN)7 z$?_`D3u%p>m-_eb;$KJ^Ybbr_hXb*aoq3Y~8?|-TtEOHL80Q-=l_)fpk>czJy-f2e z0TUIKL@&P}6=S{YxhBt6N_n>+vFZB~eh?^naw>a|bsbof8W%I~!bSn5ej3={fL~uQ z5-Du=0T62igW3nM;50Kx68((n8)_49NoCdqNbmuL8Amd^aP5 z&&I`vRYvF&Tj%Xi(i*#vqhHfQ@S1~Mo^EZN+=O77{D6$^*PUqRwb&!9h_ zd({sZZeCwnf=yP~S3U+v(ra0SinuJ_2u=16E+VX|e7m9ETMJ3s{mJ6(dKePMCRYHn zN;6O9oH)4oAgO(H|J-atR0N^9OAR_0cAM{`s`{i zsmv-82FQyfrmCe7(s!nwe0iZxM1?F8qc3NoV1jQ;^GJ1wo&USu@AxeZKPf>_+^<@DZ~ zoWxlWTSIn&it1VoNk#vxc zHvxo6{OwqH9W!OY2h*k|D3uE9cuZJ|Fn`WDUn^Hb3}5EvQsBJGLw3$UDf(cqWk&gI zIKmPMcA^=~u>HKkaN@GCJ%&C)Xizy#_#dUm=e}02=%$~TsV+Q&qR}E#%7xXKQ&qw; zpVWBn03CBSNH!l|V#v61DlDCsh#z|-=VQE%6j1qlye#WF(?x7Ux!|J)W~Z$qk#>aD z{65x^-*(Kv&89dDg+S}`)22jR;aV_@TTJET?iN=6w!#6liL?8TQhR#+c7#M(6W6Lj z*ykcSJd)b};So~3T%)dKT~+sKZxxA{iv`Pxmdlf#BP$C}5ZUM%bYzvrG5~6>U~Vfs ztYZ8_LwaD#Rhdng%RRL(b8yPT;(g>ZH zn7yU%jkaCk+*uc)ESl?pgpH#=_R=a}OFXl*+)E)X6s-^E z7v5s?4m>x<8w>^mfKr($>6Yc|s<&hYlk(TOHvamhitB$2@0l2M2gW*<*QpR{S;B{ zXp06IJuQd}(V|%cZkn}SsNfHM{&{CbK-~pTM|U#E?6%wZ_-Tb%ps=LlBzXM??z6=z zkL4@3cRQ4QqTh+?IsY}GPydBS;;_arr)T^Ej$pzG+0$`>lzvj5)l(u)KO^hSyka9% zXb=mcb6Ku)_C#vA|X))v{3aD(;7c8 z^dQX~elKgP7){!}{@i&Do9^5oYx!9w=X2q_@`C|3vbOc&gXJAsW@e=@6AK&_C3p`X z0Uo6mKX!K{NxDfV{i93UBquX*QjWjkcG}apOHL~2HB|f6!BLXRA=2by_?Vd_S+?kN zPkumj8y!efUdliG?R@aPyM2o^zhe0PUCitXx-7G%DS{aqfHVX_}3 z*CxcUrvHZch1|ECRzLL2-E$GIzN{MOkCbwF46(T$9-{yk#Mic_QV3@3B}RutrN86; za3!z_=oCAyuI{6#nLESiHrBdLS)$b_co=PTLQCA_@}FOh(mF^XyaD4%$CC$rsJN3751x;ZWv|?-b*7)tjWHBAC!-^F zug6=z7g}2!mY>pcHr-rsKYLz%9+qGJfj;tjoTYctIr=^5FyeE8C7JSjY?kYwC;3)_ z+qtf-efFPcno9-hpOEXg0`o1@D_*I0N&6y>tbg_b8J5EbozR42avBb3e`xTy9GF_n z2PT3C53cBs82WbKVT|iQXrq}11q8gONFRwrv*SwJdgHfFJvV-xu1u)z$ww5+QMtXz zZ}$38mgChN6b1^e6#YSw|Bwv!m1~Imo2PorO^LYjXX-eYO@;@3>?^BitCDmMX!c&8I--t4 zYT}QeMZlUDnJw(50=BJuH%oJI`6QD)=g!?{EYt&&R#4auQruV5 z56EGM$x1%i2^;A7w=t*gV1!%jzaeJKj(&vaydyqUcEyC94A?kUFsBr58F4oq<&=-U z1Uus#diu$S9(efUnnR$2!RC87rrCYjt?;dIZQg$K%BL}&czH!)L{zaCtMHslV_;~* zZDIDdy%t)>O51>-wlK=ssH?hK1&r+fnB7Lf-3yt4>OB|Y(b(L}1-Ox%$A^vy@J=~^ z6`8Ch7;(E2i}@zePQy}mjQ?nnLjOL(Sg#M?EDRP{+3YTWpk7WTudYug(kN2KzIOr> zR(feqfcq&O$;ksDE;&rh1EtC|5@NQ5Mv*}5vx#CG+J$~fkI%Ke;^ABS?D+ic06GFH zMj|T7>zho`Nsg5nQF`Udrwb%+Ri+(|TvxK1W7Z{Lo)(?d$T65EnDBcf^et3s_>0Gv zJ_p)4>q%si?PK?g=eOvQN)UrDUM;v+kR_)|RS2W6RYzZVr@DxBKtV2=I_bw%Q$S5 z!XDFPD&;WsYVOT=E10ONV+;6(Epwy@UUGH#!G1v2#D|^wIlPBr#h6y>Odslgtk_Jl zmi?}>WTey9Jg-4-%LU5i(3CI=O~ zOexH>kvu`?%8E%yXZPGq36I0o!q0k)a6%H*qHMfpQKJ}7+P~*3Pu^n;4W(K8@aHFB z3}sK@*gqQ3yfg<{{~*EA&$E1bs%PZ?Y^wcaLm*UL8tFXyZXc6&hxbAK)w-JoXs&2AP}R583XaGh>r&9;GY}IM?(m znk2E_6jT+YJ5Ylp<)wBZe>948-rvH@wThZFiZny5v#77!hQ|}+1^tB!6@>9c7e}&# zOk?~{qbnm@9ls&AK$|lL=gduLfsNs>pd=JM-tR%MLh>O))4wXP$Dumy5F$uAS0-iz z57|l**~TDSx3eYga|c7#!;`EpT5Fa&9u%87s)4bPaKWOsQ*4YCfh<1SlA>Zs3CN~S z)$qq#iJHG0T`6UWWrb=)JQnj!nY{`4&t5i+|1glG=i&;!=C^LYtUz(7MhU4Fsi`C~ zCp0IMCngCx-tvasF#&)Ve{(2E{J-K?1i#W)| z`bo8`4M}3Lll02?3?g)(@dCGF=Q$3Bf8P(j!E^z=Ge66IKjk>@A<<{Vus+JEYUhax zV-&CG9!4uFp%F{`)G%RL7d2>%e>|=-U;!7CoV^`b*a}c=_p?Y>ye?LRZy6unK;5gQ zDBRM1S!Cen(6JVFWnPR4=(!W!h?H3eU*25#$?6#uNT2h7@1zVcw zURGB~K1%I_vCv|(CgaXh=Q1JqY57F+fHwKv9|>^XMCsHHXfL26yD^FMZ&-ow@87nJ zw+oFUwcz$f$_}FnWJ-w#%9m+)!>SsoN~(X9RUgpVoO38`sp)}D8Y2FS^Y6kcH|CS> zcM7(yNAW;@aMuv98@doa08Uh4OHd4=gxrIV@zs0yV#+@5$sJ#l#{$3VS#pI#Sc*9JWAyJdHu^bpSh=HJB1<$1d`em zbwS@&EI{x#hotYbi%4b6#aeWaom^7urQ#F974Z0B{xX#TJ5mQ^z3y=@HbMN%>jxc& z)+@gcMghXu)s5>nyMNb;a*xaKxy6K4!|JP$FGK5`OCtsd{)l~h1Iu>V?W60F8y&tZ zXFrdZpYQ|4;_wN4as zR7i_fS!f1#D{0vH^)531C90eK-vTuHgl3tohLx=u(%6%5f8O0lR)DO1IUpKiP%)VN z5s2GMxFfksI62UKQZg%K0Q(8=)RCTAM!z)t9)^IQ`2P)>p%W z%pX6nTN!1Ay2nxfva=RW{RPUqhq*sKKHQeaPXmYGtcq;-m(Pna~S&mvLZiTlw4*lNxHXiV+?Dj6%UtOmx26uZCiZ7eodB zpvj^>O8{a5Q8GGaAV4aMuy7h>z#22;0yghPJ5f`BB;lTTUIN2+hny3`@SnkhzNZL8A@p ziGd&uXSG6YTaXRxRvc6=!q6sbK2= zLVwH~RHAbhecLr9Pm*t1yfJ2xs!{AfhocRox0Hn%dq++ZU{RobqI4rhzqCP}e?`7+ zgZQpMfSK9 z=UWmvi5f}-VJU(RqPwoDhTfR5#+BrzJNz@0|Lcbywqi}`65r%e0f)Pabftx3*;b$& z3nWy=gAP$R^ETv9Je@A-J4~+j0U`3CL}qLwh!k~ca0=ikeh%+p(*jzdwq9Ma5a6%23<_OV@Smk0Ps zO1+}zU5@grq4(st{4CeK1|Sut_g|nHBVR~( z$$*DpltTee<&k&^QFFF!_FqWAaGKPD3aDeJ?^qP4&4tq3hieHj_Pm#MO~yzmC;L$) z{MHh4(Tf-X3FUE@G&|_@DATEh9XWT3R4-MC${f;Z|}cfvtcIsIlr7~ zgNu-a!<|pv(Z(kzV4AuQt`G0Vl>-O#k90EGpxlf38U2aEfw3TH3rXvyBM6Ky3msVW zf7l2YUYtS(cIydKdyiv6MJ?b^kuT#~e=Rj$|j(_D}R#bcFq=pWDGJ#MW%#wWw48jQ*EFxNY&I-^r$Oxe!F_5fBWt@pG>v(3!Y8fAxR~b;Mq8|(x_}*!WGf+yRpW52pD$77 zli1A-g{|T6V>#5GjV|+;J@D^bDhPV%%u+8K)yNX^6MI)hL|u4dLA$+P^PRK+0j!doM=nDmuh zrFXzFo=P-m^b$O?1a8Z(b(rC$h5p0kX+T$wjDBz5gO?_+PJ2R!pYJ_$Lfn-p9!;xB z(8=6vImC=xVrH)Du&{nkJ?v$=BdRK_^Lj_Gg! zI1e>6&vHx%7<{Ov{=`mH%d;D?3^*egDnjEn5w}_Bm1mqd;vCqNY%JNHZOsU22Qx?H zvcwWL1E6M!rD;&X6h5pZkjI@x*R#gMtbqURr^LSw^WB`J$NuS%t~bDk+f&8u^Jhm^ z5(9lnki@Ibzp&1?lBx&R!Il*{qnl8q5x)^t+D^h|j6-PJu=7%fdR!jTLXSA(}Bj3_ZC#qP;XVrw0xaj#7Sa9=pj8&L(k9^5g zEQ-o6kjBt|ABKME1he&iX=2|TGufE&U;XP?412G1G8-bieKH;B1ZRCFhW&mXZ(_D) z1ZgTtmxbv;ak06c*HX7{PhX`uFy{2yntqeb*LxlIA!fs5z4|eGpQA%ry6V1dz{(E9 z_yh=+hQPb@G;>||ZTB!Nqdw;pa!AwP6Wu@4M&LuAh#?DL@g(eWY!HP}P766x^M=@c zgj_Loqg*9DGR_PNT1;awIujD4Wh8Dj~`3;la*HB;5`gAx}WrH@=Xnb zvjHT1pH5VDXYgMib>orcg}k44gY&Ct;MvF|ht34Vt{m!@t{$`=NRpiECB6-da@L;e z!u4o%g`H-oob;L^_pjc(^uN;{X!&*t4(~F%QAv(9VEGbxiy;j1*EXavngg?m+NiW7 z6CWG(c#jT>Ga4GudurDB6U$()9)_}m-5hLXk{TlgeL%Mof8R@nunlB`b^}(sJHFl` zwy6&<@k|7Ku>N$cvMw*umzgfBla)tIY)}R6>v6KJ-No$9U3*~)AK;tNQItXG$tOS; z-0h|Y%&DTUdjdqzVVO3ZDL|s<$%Q-w1VYmPKm)*=*p~i*e`%|X`}YNwg;e71l_btq z1Z2%r!?LFDe7@^T>Pc7y-?(EdkMq7A5EV1d-;V%y zIZr%S=HYK{Kk#&6{z2@D#bzAY&^<5yJq{Zdas*dr7p8+ndWg48ZV{*6SU@=(B2E;d zr>_gXGOk1cB{9G^eE8bSmzA;9v0QmMq`6l5o{;D-)4Z|ol3H(jPP#I~MhJ)1&@t+-MDKXe zJ#8e@Hi!}8BQmR3S?-X5L5-8(y)uBuamw%+6_Rw?J0T1gAt&}Bwde*~+d{6sL|3Rv z+|q~JG2EMt*O7}f7=GQv=OOKuHd5j5RsYNqrk0by1w5KJQ;(jqNl?bYFF>ByuPnCJ zaz%kZ)`_(CNq!h!Hte-ek;c~cu=)NSQjRH~;%n}E%1p9B!{ufQvBG*744B|PQ`jTFUG-MOefb6&XK zBfUWMcF-A4UT;BTVT+xc9Sz!V984aaFiWaSI=v~3waey02jx`M68IGabBF1*-&z>7 zM2y+!F0h0>a%K3|1}Y{8{MeN;0wYQc*-$A~%TUDD0d`eIh#(YcAu{7_Rm3!Kmd*8K zzSeDl5=&)b?{f6)9z$xvTp zb{eHEv^fwmlV>GSUFiuivZhKMC)Cs8O&obv1V4@so~fbJmkd% zdXb)!O&uUlv|BHFhST?qhOq9X^mb{n+ET8Y#2_8`w5Btw=6}#pyG|N=7+Hv-BBsag zG2>nl(C*Jn5F%-qE^mzsOgmZS^ns>Hxb%YfM>MfL8Y|}bM~3IkQ_=m1ddE6Q`%&u; zrUVmhPt=}Rhd9ub1Dr!FPxBC|V+_*Q(5up}OdIkgm^{LtRN<)K9n4Zb-8D9rKnSZz zF!cJ!XCfoY=Va})|5MI7Qo_7wF*uNotQd^%Eg|IW8q} z-vIjYzy?+2d`FV)#;)Pi;CW%J9?#=!6Sn+^;5~izv=HRFEVe@mmQ zuN-CF*U;M^Gu)6J@k-F9sXcHxP6SLiQ^WW?UXz5TWvS<4E))jEopp>?>+f3 zwYF6UwfHdAe3EcZaaR^Gng84h-nt`SjIhN-p#vO(zazh<)qe)tyHT(lHIA*hX82*H z_f9KY&)K~79?LKHQzE$hS-yxnaY1CDdnZp3OTcwtQsqjdzb#$DFy&sde4h!Khr(+) z-aq!6Kg@sBBM;hxya3k8aU2zeFTJp#HBRR^p7Iw|h({2F(`NDDYqP4uE<59O6{>|x zv44}|WT{h%-cP9(uKR$7myKf5(Jo138T_0{gA2>=a%()#!LSDU&{W1`RIN&d(6Oho ztfnAz=qb*w#NulR6OZ=b46Ul>?sISag^{H>;mQ66*l{)sS8yf&y#jJs#Z&AP zIHci$-56k{N{0a;C!%6HCeh!Jnbkxd$gC}&2T)BQPXF}DD-z6(?7$aR|7%aj4G3jN zR7GoKmUd@*2XZcj#3n3i4*4CFds@u1Rzn=h4m=jfKgl2t+SOP%r9pq}^Kcc}^y?`q zs3WsS0{QAFVux(~?kEm`+?4%d_x8`4wWtnwc&UOMy&xE#U>vg^>m%6SSz(~wQls7L zub)>vsQIM!KjDAoU!t;M$yO}pp!!78o`i4WF$YQQf;;ZCqVQa@aJ8-d)s zV$_&}F7V>fh-`qyGf^HPX=A$|#oTXfiStV@{m z4eyOIJS<%q3Z)9M^lk>y7UrU4GU4tpgD@rZAD?x-i5HkRLOXy*lK++d;j(FcEl z@U}uLJG^~Ok2P@YvW#d%H1@q~^WdcqG5qZ!UkOVF0*gYQ4_@ffylwOke?X*=JDo47 z5Eu`6&V&Gg!uS2d+?N6AG#Ldn!rlEodN}qtB7fw^!l=|K70ZmXIDGc(cYZDOs1zLg z+}}!~(`%RZ!b+8oC)WrFc`KvSSFT&Abb6QNq#IWb*8WC-l2bECG;j3&&Xs8VRJike z4T@H**S5f)y&C2Hm9js6u2g8l0-X~v^yZxF1Nu0ZyXv3~F}f0QqxS8zhKM;2^?2Zy zNtb1Nn7*^9XTar;6>|iBN+R_=Q0DE`z~B@ObGF+ODEHJ_CcP&FVf0cD|4`NtC~asU z)))(!rB6fmBuz`_ZT~Y9S%!fx^PAUmT}`pK7j!lnW!$qbm84RNSV>R+gSi0$);#8L z@5k=da^2YMCfEmLI}cjCBBS$Y3!TS1$46vo(tAzNO60D|@|3p46#D~`>G}8@Wg+@+ zK%Z0+$)CY!EESeF7sa%EanX}Mz4zUgn3v9*H9o}AT{@*K!=I++q(8`zR0env9BGtE z))SiM<6QoB464@;9A~E8-Id1FsPQ@)jJ3$wqhB1K^%VLy6a7o;QQsG&`ZkmPArJET zUXNltNRI@t042?0;FF&XUmg;Vc|GnSZXBj*!$P7$tMLY2nUkB&$b^BSC6G4~rpiPqyc`u-o@mY=W|?qq;WNBj}6v!khZ(X*^mTA+8BdB9 z6#$oHqNZ0-2iXQ*dmJYj4_@rdm0A(eVix_2Ht%mzoj!OFQJ>_5oWHJ)4+qA)7$Ue4 z8Uc(<<@G&SJBgAbwP(QY+E(EiRsDkT@%hipj=w|IPptd9mc$G>+w|agYdRQ4eI->1 z9j`iDM*XdWmWfnRqe|1OB~GQ13EfBk;w$}I*`R$531C>-^jSS=BrcBL>V%!N7hPCd`T}DW5E9-uGiz4iJoABr-Q2js z)H}a7{HVGvSXARYlRZ?XqiCba=~*yRshz@L@aZ$5?$V%Y_h_p3GU zXk7uo-MUgqPA{fLoFE_iGWgr|n9QRLB4}E8yIFaVhZ)oq+2Z&|8g~*m z$N+(`T*(&0lFQj*U*q(gT`_f(T82NFN(y!+6ltQPx zIqZ(=XCF+T>*-leU!DB903k~{>V)k6Bw0EQCP$Y24DE z=p9_m(&W~CR?42+3xA*vGZ2U7oU8LeQWIG;ZTYLgPQc-))dUOrp!26{;PCAGGzxWC z*RQwIXT~Ck8dopO=-E5)0l0hZhidaU$IE=OqHTgy5DMcMz`sj%^4R@`cb?W7p zBYCOx@#CjRtN7OWC9o&D!DF4cSdnkli;lb6-h*%7!hVi@w2WZNwm@c6@xpTpj9}GM zMR*~)0e@23!EzZD53fg#+-Dm^-Z>ZqkPep>rxN7O+8Z^Y6lNj0sH%w>5z=WPNI2>z zbr8^x4;(=dF|Mk!RJF^M+2bVcl80++ru35e3xK?sI@|@#(GR4tXpXwTVdcs49A>)e z5#LE+2#l;^$uU(}gYgq2G3>j*Qt+8H0mNDMU! z_SUf(ZAB6{{?CH)BIsYyxf+Px`#T^<=1JP4)HDS*77=x_X9O*=lmb0C7;BFs4fN!D ziCTmYR+BL{gt911wG|Gkr_*9AJyMcsix;4}J!)8}zm6erHy+b1<~T@^`Po|)mk7Bo zTwD_Ok17JQy^ubNKx?w{FP~)n~&G{53OW&aw2U zP(u+62MOB~%H!SSgWgYXE7B|EN{+iE_06pw<#Zn3I_=?q;4Hy*;3X}*xPAUD;<(MZ zb>{?Ol^Z~jG?puiC$4&ZEY07V6kTw3{)$ia{z;6?oVn93wc1ljv)N399;gEjw<4hi zd|U>Y7yk`6R5YGK*PJ?8LkTQ$YavEXaB<&S*9eG7-E`U*S9H8gqP=}zgJersMdcI1b_TF1i*gyGr6e0Sk1JHK3S zk4IA**K63REH3qjLtbRE05#>T%Q$rsnk!@YU+>m;ySqqyX$e-*50i2AVCt;G72*co zso3fSNNc@X@yx0!3Ma_h!Whp5fK0?N7$@PCxs3giFEFjClr$Cxn zCSjjQD?-tS&(cfY0#407$S$O;q(;_3ICxk-a znLqWwct#CsXmwszU17j*fqZ<4+Co2HwFE!IgU|-+$e}Oh!=E<_gw{D}6in}+8zF?n z8%V%uU9#x}`G~(;jH~)rez1e`!v|`qy)&<%PVq|a;};nHDrD&+ToXmBld|7L;=fd6 z_o^8dNG^k;VA)BP?Id{unH^&i07MJ2V~iVbR&hx^|2bd9i4l*_>z0JMi&fXL_IZVaxsDMJ)ZZbUrf{VRxm_(*f-ORVDVue(_07n+OF6 z#w{6og8l`z>dJbgUT5Q&05YnlCDzyej=LxZfbhDyjYmsUt@>`Flbp-<=!*2iCggN_ z*QRPKQoFD(wwmTHeo|z{?R&>S**?s!!J7`>i5^x`wCLzKECK!PyiV+Tpk0;B8Y}eO zM6AZMXrKgHE<W;dHxz}V_xjzvcXHGKYQNzle`NbhS}iVaq1HffpPr&@Uwfyc*8L4utlG);u! zWmxlvGjvq;*np$*874*E$5}NNUJ{&P*x{BG`i4*laABGJ5W@+{Lro3X*!*NH?$~*N znIR*B^T5FZP0(s~{wG-bhxrd(yOgG;gCV5a1GibAAyFE8m?9Gda&ZX__H;xMn?NqH z9)l1*f1v1?!L5&4)0j9fC6^dSILSwn`Q~-!M^srE6;DandsoWl=R~)x%6$VC`^Zdi zMWj?a>hWLb1UG789iuNS2jV~VM9Q58CC0w%3LNM4o&+OvT1h<_^H)SQHHuYSf^?J0 zEV!~kU;AG{%@#kzFnK5EJlhM}A){|4ks#L-iJvL{gj3k#v|0a@dw7A1l8Y2Nf@6XO zl^Az+{9MHRQyQ>}YiyyF2nb`qJ{+G;U%mQ#p>!5A?0_3Wu;;qH!}@ zP#bF=alYJ(!lwFt61%CiAsV@eRg9_TN|>_J5N7J}P7g+8(M(*c<#6 z>^eiB)-e&`5{{mfuyz`EOdZtUncMamyjoSyF?6UxjLyff+-OVqj0ciWCqhI4e_J_G z9Xs9Sjppg^KI5hLUrf4u4H7~Af71B>OHYCSrSE@_OWV5{+gh0so7);&xPX`fJ%~y8 ziJe_tfGz-2M;3Mt8)ic{CPQ{ZCPPyPdmz9AXlUfXP`j_GKJMGqaZ+6oEKfZ?+2NyecV;4JmHg+y9fC)DXvpJW! znK^)kk&VNc$ppa6=xA(eV{8F%VRQjHIR7IUU7SrBZ2|TcK+FF))8mmLWb z5ZiwSfcw`e|H}}@Kp?=*5l9SlAT~BL`*((cmc$Nj0B3VshkwbEww}Z;u8xil&OjGp zdt*C*%Rfl~7h+e(|9JmD1rRfNNc?L)k|ZE>|JM9(8D#%x*ngezKaQ&@qd9=xgqhWh zgNxamg&hF+7aPK60$|}b<7DG9QOMsN~F6UGq65~2uZ**L;@!UTfH zJ+QE%tjM##U1(~CVsA;Mr?RlL#9i*KtST=tH9?8nTV75DQdQ!eU*^rN^yU>U`0r+m zr>Lkj*LQjSm5#{<+o7Q`wh z6oN@-CR3GkClpd4mzQ{o{P~vUCQrTPztCHh=g!W)j`+GPzni&< z&#NjcD$J#T22-$XGja7LO;yR9lG1r4?zx`wLQhF0TZwfCi-wzY2LtI(FgImR^YQFj zJ{AAlI;7k?tB^9Xz*ktPPztJY;&`}qPxR*IrX^)&=H+C1b2E~X<8wR}+>hN8;u4eN z5`C%jcnaqE?l7CJ{fHQw*~eR)TwCTrKU&M*$D<|wlUnhg*NXqPR{RgO;(x0Z|7Wdu zhyC>93Bh&$QMKah){1XjE52DE-hb|S!OAVyQ2+k>;mDSseM-p$IjXh7UEgBZht6l z>XYF9M&O-lc?0p$#G5)ln0_YSP`nt|^SKz;Yjy>$`(KVXmi2GM6Y*iiWu@GOR0CP= zVjeGU--D{aGuP`*Fb}4TK-0@K&P+4RUF0EAZUOgQtp8$^l(N|0K=ePwDjJQB@zqhm zV_(g_^xQY$daRG(=3K`Fo|W!-1>O>OO>v=y;Mr~3e>qk8`QGwCc{-Ihce1W2JO8Ke zU2jR?-VHW@Cruoj!G4Z$e&#+-A+#cxI(8Pv6)e4Cj$5i`GVCDupADUD`^UuCLUB_bj=^Ln$K<~x{u(LE{RPYGv3ycVpb^3| z;Jhkt`2u(4f-ok)MseASnhrPIWJ zyL$7unGUiYbI<*w^|}0|B{Z&zsFHl!&;_!cW)ovK zyJmSOmX`X;vhPu13PXXXtjt@&)iynT{`GK+%;L)VO2_0;aWh!o)TzPqZb;>2>XV=+ z1Uyg$52XXo075Z^{lB~m+Ya{8L$*0Qu+2ffu7s)M-AOcvePazYNOQe4WyDQOF7+QD zJlm`{DaO`Mwmq!Y@z1X1g#q_T}IpOY~SSX|4g|n zrXDI^K(QN73zu8AtkhRS_-dG{BGbQZIoV$)@8CFQ;+X_fF9ueqsPvfrESIB%^uhIs zAIW;HnFrVF6IgFRu-x^d6i*5?-hJnrOVNPyM$vf z&!Iq~vHmn8ybJsrqrXUQRG8}&$S~6GWF6oAQaHDea-6fkZ3eEg-0!g5JkNq{DyjtA z4=gk7BupHF%-mJ-aQ0`L5q*mcC2 zHb^ke3NI%(wcVJG3KW26kMmjuXk3nN!u^Pn|o`Bw}iaN zt;yA9Q~l*IaDm-{5yzTLPaxj3Q_RKoJ*iE8asp!m>rG~B`KIG4m#Tm`bNr_+V(`jT z@N~>Qt&Ghe-9X>?v(D)p)Zb8w6g7UGY^F~z_O{mJDRtc0gf9J$kH+(eB z-#-45c?j!#&)n2u!F*)9rRAk%W-N>=cKZ1ZAe}F&Brh>APdf7&`nGV|vE{O!uZF5A z{J#4$c!S!irpNgDL`#^PGOE}6)bW($75dxp3>x{G$*0uc!e*e|G|7Df?`Ci*FdR~K zs+AvHlYKnGzD)hPi@B*AUJuMaU~c*kpD{OmO!KVwnmh@%;{!VnTw!xRFfMa?-PLzS zjIBBAo^~(cc`T1+-rrM6&%w7<+l4HPWLaQ){-WWp<9x|D|1op;&j!+&I_N>>4(1-6Bq11&4LREx~vfYf^C>-_=GW|X_T0T2u;LdkK2=PnwqAqT4Z{* zzH4UMCp6hT<>mfnV6mqxu4YBkGM-n!P^xbL*KLNmicBrQV4ArC)X=g`-{#_cHyV4S z2}dKdimaVQ1p`7p?Rk5O5NE#BW_I2Y}0Bs z&yGM>fU3~<-Xtz~iK=MZnRbouKfb4WO_Zq;g2@;G&f%#VRBuJDhX+B0DQh%?;syn3 zR(}(@<^;`=_#XV6lJ9u^XL%|$Eqh--(92L6nd@<9SC&_K8JWw@_Y_qaFwIzZwrMkD z|FgZAv#;4kr`S%}ffYL~>?G@%jGcEXU)`Mt4oFCNzxw)tjHP$^cQ?;rbvoztt(#uO zX`9dRZ@&M(-n`jbmf6~v!RBhywFy2-PtUr)i4I)Rzge@yUFs_Vf4kKp3Q`<36kVyJ zQ)QAy26eqDV1dp4ZF};+JkCkmA*gUU0o+RxsllW|H)OKOQ)m<1vkfeiH@^8&><|dFK!~mRs4D8ISrO z%!A@m^OA^t)bseq7uv&Sj4S91;dbJSVDrwWzki5}`#Rs(0AJ1e|C7hcm5lcvtnb#e z?O=cAxq66Tj<;s$z*lwu^Y;fSIsW$ttmd2k<@E|CJTv_n<>5cOR%edO*NpA4?;RYs z8P8imFk`Y+rd|2ZM)P>7>>uhpwXP{srmY*?)>hapz75W*<>sCUrvDi>?dhQZ0h{qb zb!_P2T+mHFIluu1M7+8gAJ_E8H9i_QZHM6cQMKah*7EuRKQ+G0 zxKOc&#-_KtGSA-@4sNR}X-#`N=skk#28Wf+gSlcsaSk;akB-|P?Jj~Tdok_KYTuz_r_Novc8l$vkeHO5 zlA4yDk=eIj{{aIB4IVOd*zge}M~xmkZv2FalO~@%b=vf7Pfl*0x1ezLoTB2g^U6<8 zHzts93MqZ*@@M%|mXwmVqOxl4y!i{xKed}~v2pSL*%spBPi^hLv!(yeI;Zy7edd3* zez*AGcMkt>ZnNwTrz<2hEIcAI>g37jI(6&SZ_uz&<0k$!nl@|RqGhYrZQ8nhSMp@w zQl9Ki#+VfTD|+%I*EFj~&yy#6_3qECph=@jrNW-IZxOTOUb%-FOU^9zoj zn?6w`p^CuUCq4*uXOAf}<8E15RVDMvJ!PG{a31CrWH#M7Z?=C##{Z(i?fYaa@C8Y} zJ1~mu|E`n<&=c&}^fC7{ufsg}{TrWd`Ht7OHr=vsi1)n*2(&Y6r}LeKc{NDdW~KhI zWdYxE1^SztS=W5mVcsK{Ht|J-VBTL0R}&Ty zbot_dGxL?F?#zSxKJ}4Yxo6(Yx!zpzgh3(?SDQDaypJ#+H{ z7^^4ndc*fh+xJP>zx=rG%w6XfSDN1RTDEPj+a$Ja_HkxH1~*8!Kag$}*S9C>f_@L4 zfPcO7$-%r&H^beGGM1M6UPiE7^JEF`>+;rGz7#i8ptV1*w2DvH7^X6BUCgQaUYz^H zjI#w&nb)@!#bl)!Im_ohG4DTpL-D?sDUzzlEdBdbg@N8sULl`A)E>_Xj28Nb-Atd| ze2?OLrS5;}9vJnBvsvZ-y5rxt_iR`BPuW*Cu7*dR7vo!EI&<^Qw>hSQ$}s~>60&Rru>wv!UR*Ca{cR=R4lu{eCUJjBp*nZKew%Vk2Uixfi+@c8=&A+a+SUp5JoP zof9myH6Ke-xZ^1Sl-q>)2?+^_2}udb2`LGw326!G2^k5Qi3y2`iAjmci7APxiD`-H zi5ZERNeM}bNl8h`NhwLGNoh&xNf}9*$qC7c$w|q{$tlUH$!W>y$r;I+DG4cwDM=~G zDJdzbDdt1rjFimOgw({;q}1fpl+@JJwAA#}jMU7ugtWx8q_pI;l(f{ew6yfJjI_-3 zg!IJpr1a$Ul=Rf}wDk1!jP%Tmgp9SW@l#JAjw2btOjEu}o4l$G6XR_%`R?B43 znU}6>F2mmL-tNRqo9zIU@aqXT5X_*lZ&a$>Q^H;0A9D7WrC_P^ z$C&%Bf+vvgNg4Q*n)SC=`pei$%-i8-WW8^lc;6OH{bH+%@zwDuq&3Io-?-N|ZfZ(; z0`aCU4{k4*epn#A{}B8KcI_5HuW**$ejKDU`H!bGlXWk80 zRpxj1zbUO5k@w%y{yo@itJy|Z)(h4Q{uP3w_vWSyJ|WH5L;kf6vyOQ-e8=3}f7buc z6Nm60PWFE~IciN#Gszy$EEARG{0#tK@|TyGGSO(Bzf82CA!XVYK_6PnhXwp^x91;V zogNn#caCp-$$u$K6?t0aX|7l{`&i08BbhH_ZpuoqKFY(*eKUt(p6xk&v{B;j*^4(s zdG5{zy7-5sOhGiSq_TPTv5sjAy~o^~_xsFE8Lque)AlrFKDZClCNb@RQ*W5e>mPqD z&xh$f_;Yv@#TRVmvjcZ${|o&tzEcPuf69FS`}}FlO`9l(xoMBq-nVI&n0=p-cY(K9 z@q8`8p91ht<8o_2cT&|E1duT{lXn6gIR*}u4T13~Y6J6I?&(WYk z!|*0nQ)e@)xuZpBORJT=Z4?d$FLJ2!;=X8+ywr~NO-$?yl~ zFSzQOdlIIcebv?1wR*Qs-4P>y|06EG&x~_szQ6REYnQKBzvb~K_UwJ(#rHluank0j z-=IrkN_tk0Uc-i;v-DabA9?(Vy)VAH@52)|XLKE3Y*vp!gNF@2H_y9t`R#YU@an$k z`dwHwY|8W*=g!RYUbB2XtL%B<=!Yl1iLO6rSf00f=|el7+WE$zZ@yh}$yKY@JhgMr zbFc0@^7hbMo_uBRtNVtH9y4X?xihc0cG;G#+jc&)_qjv$n>3w1c*y86XHT1P?nM_ry64~7ikD>vf9%>g$ry^j>}X54vvogjrS3zp($n z;kQ2i>!i&+v)$sO&cy@6S~^4OFM6O(^#)hl@I@^h&BH8byfeia>aapXLhDD2t=k}U zQmDh(Dk9tw<_LAzxf!FJE=OdDRj09QbZE=aDWUd|CedS^103BQma~3H-KZ>Q>kc#B z#m?Css-Jf)-t1@*viMKO)X*m3&B7Z+HHw-Y5)slOWNK(P*Wid)XOz=&Bu2(MTZBY9 zsvjUKK5>+zdUaS&M_otH&!%_AFMeuFFC)g#ni zr&)OQQ|&6Fs^4r8<*GjEsy-U^-JOo~@I^BkRX-M1{gNx9Sr115hSgC`or$ZQi;i>*jdHoF*VJ3|W2ois8ba(f&g!QeEgf~E zZ6TJ$$=O|@q4uz_aC?L+(q6||&#G^4;A&XEk=5AV)ZRS0m8*4Fduz6Hj(wA3hkc*@ zfc;?98{u!-5801c$6UwlA3Hy>f93wh`HP)`YDIPG(R=imWp~|m_XSs7f73k=J$~ty zkkIh7UcD!OzyE-2Tgz6VVG)sy znx?ohRM7a@D=7*RFf; z@g2KEBBL6&&gwI0+?us7zp^s4d5d-(diVMGi?2`a+3R$l)uChONjHobAKgxVpIp zI_q?;zCWbBv%Rx(SW4vR0gKYZn?!^)>oF+PksB7C(8LwvXz8;0W;jQ<;++wp;h}xq zot#nOX^t#ci%@4&=-6TD$osVH2WXvCtl=GEJ*x=GPXZqKiZtloX)$lU0q@yiY@ z9^&l&KV&cBL+uwb~RkQdAfImGc&Y)UsDEd{v~Ybn_a{2`FK%scSn6^*rKbi zaL#c>JHkWjt;ik{UfHwyr-+KMvc`j}Z)+4aCA@j{Ws8P5F6m#l@zSwvtB-f9extji zh10&MZ`=A=E^Fzr>YuxebVfMsOX?3C*{k~5o*|ZVlB;EkeNmlQXI|9gi0X|Qt)pX| z;gtK3>f4qa=A@$?l~Geexr^#XIWst!&SC9FFPa$D*x_=7hPQS^xyXv-%=oaN zFmGm6+04pPUuSG4jl0v^i#M|FW*X+_G+b$K(A3@T$+p?;E{t_2xDv8c8m~N-`pfF< z^r$r})7$)hEZz3ku>pTto`Kb&F+;70<3rm=uNt-?(l8>`RkPF9E&X`Mx@YKZ0JzfQ|;w>|B&JFRfLW&Iwy&vIFb-HEXCj}>c0 zhD1bKq>pG^&+>*@5tcKC$TlsfM`lH`uGOqrH%F{REg9A&E8T1_j4CfQ!X9nawX!Uy zGt6paZ^1q?sbHLTDp;$H-C;!2)|6yDQRaA8zG4 zIdNKI&FxM{J!do+!V#Wp(b;mewzuJ*zIH1#%(6#1SgE@!+3II+XU%mu?cr94<88a0 z{ac}CtM;&v2)otE3TvC_Ot47Izn#OQ>~2oaa%7Nz19D`A+3kHp#yhNNE7a`TVNdE4 zZME~#pmju2uKC9v#A;*^Oj<;-9dnauN>zt5t9CU9( zY*vobq-^CJYp>I8wAIux%i*wxnd;kWZg*KX+gmh)Yx%tf+eJ@b#QUJS_BOHnB-E1?$N^-P!Sz*1cD0@mc z_rEpM!OqG5m6ju{G1t;zbqIC1c7>UYYidoTJdnu#l{19@wzN+QGpT2roF~TXpwPH% z;g;QIii~v~dvRLsh|VE)%1?NR-4VydwV4CA#y7Etn(RG4gbj0bEo-RRg+)g>+{W`Y z+-bA=)aSZ$^u(GiI&E?GrZz`-J$q;y=M4^9x-%)vs$(^AS#{ZFec$$6G+3=(PFrYk z7|lYfO?LG+Hrq-Xtt%TI3#o494r|hOW!TpCPlwxL-3|M$$!?gi;aDTv@7YabPP&`f zoU58~e>bm=I^J?+v*WG$mUvp*4z6mw=FQ`+ZATZivwiC6knrvC4p)Ag)UjWSkQVXe zA1B<@YHRJ{cG_>X54E>(Wm{cM?s5Zjn&y-mSre?Q!q!+F!@Jlzni6U6W_Q>o+e2*O zp-|ta``YXw_Kt)wQk$u*J=Nq0HzW-pdx$fdJ1w-*R|dW8k%Gz1$JWh60cMHQ<#Jl} z-TXCPitR**(_xSD?a3C`pv}^J3PBH3rYu)W?gCpkD>`(njW&mkbFhug=4n|ONuf5^ zBQQ5F(|o0fhoP-6|4gDvqQv;lD~c_JTKy;pR0>urlLZ`4D3`9e)ttOIJ%rgJtVXth zW?$^h_s2&|oNn84SGK8lZPdGMqukkTzm8qmt!siiwsg(0So^x{?rnb0jZxW_xm-I} zH%HH~uFWjB)}E%eqsW>PZAJW->QD03)Sr$B>dzjm8^xNP|F#b0@=%MKI@Q#pr}kp% zQm!(kDa;y2eHs;(Lwy?gZ`7t|)}`SV&1S3WpVp)arXHmv{-av-7O6w`_O)5N7$Ccb z+R+wLXztqxw|%Ug9u~*`_cdTAYd}r?7caG6SBlnGCflg>Z1w8ZqgL?OZU3@X3$=Rv ziyDm!U^TJoNUcVWaxN9Q~rzQK{0d7jD4P3V22&z)LJ%|cnHknv1ST`!^I8 zw|F18uXsPWzxV)np!gtou=o&osQ7Srg!o8!l=x_PjQCiX=S9sl9-bgR5uPMI8J;43 zHat~)8a!Qm27HbiW||Gp5if#^#Y^B)@iO>4 z@p8CAyb`Vwp9{|upAVm`**kSNe!j$C0ADD+5WYx!5j??uY6FY$B@(|BzC`>|c%r1g z48L6BuYe~@{FV3=@vHEwCH=MVyW-2>sgnLWe7g8@e1)XH9?q8d8}MB5n{e7|HPg*_ zf%q->t%Tro2V5%gcjD#ZcjHy!EAdr?;B*gsulQ>CKJhhhwXDAuUnlYF;UyCP0REuF zZ-g(G_)Yj`iQfWWDe({CSBXE2KO*TLg|~`tgI7rU$MEeEzXN_!d^fyTd`~TZ4u3)7 zpReUF;x9}5OSSwJ{8fqH2k#d@0KX>wI($(44fsv*L-1kox8NhC>SOmVSPZ1E!~5GdW@N%}a1Hzo8Qmejt8@#1De679R|oZ^DApP*6u$!AD1IfpN&IT~W$|m_SHzdWuZk~+w}`KR9}>SF zepsBbKiebXH^PsK-vnpehd7V_^t4E@!R0X#czk75WfT7A$}+Pr1)L%Q{s2S zJH=PRPm8aDpAo+o-X*>o-YtF~yhnTuyjOfJ{G9kY_<8a5@C)Mi!!L?&fL{{d2OknY z48J9Q1b$om9r#`G_u!-A$Kd1Q@53L6e+Zut{|NqA{1f<7@z3DT#lL{R6#okTTKorC zum8{ZFB1PN{GIr3@bBV(!WW4D1z#wB5?&~7KAsp$2u_S-+s298;ql@Qc!Ie3=wza} z3!Wq%0#6nXg{O#z!Dovzwr-m$9sy4ikA$a-N5M11qv3PJ>%ixV*M(<_*Mk$p>%)oS z4d5j4hH$cYBREC8F`O#i1Wprg3a5)VgEPdN!zUN3&k&jFBY$c7l~g9UnPDue2w_E@G|l1;N{{g;OoV2 zfNvDP3BFnU7Wh{2+u+;9?||%z-YNbxyifcY_*wB?@NV%v z@Luuf;OE6(fL|1U34U4p75G*0{qOY0Q;_t&Bh<^y55dR4NSo{&&9uhzZCxp{#yJS_*?Ps;P1tMfPWPK3I199 z7x-84-{9ZH|A7A#{|i1TZay&Ny>`uHhaKWh*d-nUhl+>6;o=c+q&RP4ZPDU&;JV`V z;QHbX;D+Lj;Kt%j;HKiu;O62j;FjX8;MU@8;I`s!I7Yl3e3p27xPy2{xRZEixQlpK zxSMz^++92lju%gaJ>p4lj(9ShE1m-9iKoI|@iaJJJRP1To>#XTpWzS@3M}9`GFT zo^X+PFSuB|H(Vm#2QC%w3zv!agU=K150{G%fGflY!j`WbU^#GyufnbFHMhI%9^5W|FYXXujXTBf!(HNQ@DTB}c&PX~JWPB&9xi@A z9wEK~j}(6Zj}m_nj~3sE*Ad@@*A?H4*Aw4@*B5^XZy^3K-cbAzypi~$cw_OccoXq$ zcvJDm@MhxM@#f-><1NIWz*~y%z*~twiMJMi3U4F66K^a2H0~CE29FVc7H=oM3qMPI zH{M=+58griIlPnjD|mPDl?}PyH=HVOtMK#0@4?H(@5L*`SL2o9_u*CIYw)?^Yw>yF z>+t#F>+uER_v7b_Z@@1Qe*nKw{6T!7_(uF9@lE)};+yem@h$iw@rUrm;t%6X#2>+z zia&~9BEA*BRD2tLnfPP)<>K4%E5skiuM~d*ze;=uezo|M_%-5B;n#}q#FvRbjbA7J z48C0aS$u`~F8q4&-S`dSd+-~@_u@B+KZoBe{yct*_zU>0;xFR2iNA#3F8(rphxjY_ zo#L{Xgnuo*8UIFn z3;wP6L-=>%598m9KZ5@t{wV&V_*VQU@oo6e;*a6Kh;PS#6@MK6P5epxPw}Vlzr=Uq zC&kT=30Q>SWQQH%PS_C-WTpC-X9(yJ`f%xJ{TS%J`^4%J{%q)J`x@! zJ{le)J{BG)J|3PRJ`tWIJ{g`Oel|Q+d>TAmd*@od;5o&)EK=fPg_e0Y|4 z0bD3P8=fOx1Q&~!z@_44@Ok3paD{j!TqQmio+myZULbxxe1Z6d@Ivv6;ETnp;YH$$ z;U(fr;Y-9Xg)bAo9KJ&QO86@AtKn@?H3hxu&4<8VJ4Srqx zApC~-oA4p=!|+?;N8q=`-+|v1e-Az?ehfY?{yzMH_=oTb@sHq-#Xo^R75@zWT>K08 zOYyJZuf@NCzZL%u{$BhC_($=d;Ge~RfqxbM4gOvH5BN{@D%X^I9t3B_K44h zbHwMsx#C4|o_I0r6)%DF#Y^E?;+MnK;#a_n#IJ-Gi(dsV5x*K;2Xs6gl`nT3%*JGZun;Lb?{2@_3$e3`{8@UH^BFb zKLD>5e-OS;d?UO@d=tD@{4sd5_;z@U_~USy_!IDX;yd7n#h-`E#b1Cc#9xFf#b1J} z#9xMYi64gdi@yaQ5I+LX6@MF^C;kb1O#D;$xcF!A`Qo3$7l?lWpAi2Ao-h6@yg>Xn z_(JjD;f3OVz~75^j5+;#tgiT+;KP71s|;xEA`#9xL#5`P8$So~G^6Y+iU zr{dJ#MqSqn}Sx5G)|4merd38#p=;8gJtI88hhP8Sb@GsMH;Oz{XfOFRyiC+gV7heHiFMb1jqxenm z&EmJfw~F5e-!6U!e5d$b@ZI7o;Z@@I!1s!;hVK(!1Fscd2d@{uAKoDT0Q{i%MtGC> zW_XMEL-51mkHC+LZ-uvsKL&3Xe;j^7dlNv_$~1x@Y~|=!0(E`2Okwb1|JuH zAO1l6bNCDKFX6Amzk|OQ@4JTQ1tB=~hX;rcga?TahKGm`g@=g`hewEyghz>whR2AH zg~y4HhbM?ngeQqlhNp<14Nn!H22U5C0iPp&E<95_8}^9jz`5diuva`Eo+VxY7mCk@ z=ZF`<#p2cQBJsuW67i+*CE}ODmx*5vUm<=ae3kgs@HOJs!pp?3gO`i1fUg(70lrcE zCirIYTi{#8Z-Z|aZ?~557D8}p4|fpn2zL_i40jRl3U?Eag}aN#!SUiraI$y`oGP9M zr;BI6nc`V+5AmLGFY(@RAMw6$Kk@$X0P%tFAo0QQ5b>e#F!AB=2=S5dDDlzo81b?2 zIPvlD1o4URB=O1c6!Ej+sp8Y%>EbisbHvYuXNqUT9`PJFS3D2)is!?##0%g;@!9Yk z@glfbyaX;4UjUykegS-;_(FJrw0ADTFP8Xfc#-&Gc!~H@_!99;;mgFYg0B|82KGw( zb^U;xQ+we+a>;9o%31EO>x;dw8ID2Y8TpM|iM!CwPc>XLzW17kHR>S9rL1 zH+Y12EId-YJ3LA}4jwHY504Q~fX9j_!sEn~;PK+g@C5M`c%pbJJV`tao-CdYPZ7_6 z&lb;wr;2C6)5L8~%hs6?oXpQobrI*c+-zON`8_pTH*qH%E6z``*}9AK18ufAaej2r z7B9}vGV=Fvr}iHXCyGbFN#gvtBYz)vDm}l!$=}DF@@P0!ybhcuUKdUmuLoy{*M~F3 z8^BrO4dEW*jo_Z*jp1J6P2k?*P2oP`{Ms6SA9w2bo5TIYTfqIrTfzgxTfqaxTf>9I z+rWdx+rmS{-SANH7?7k>i&Kzs-Mq4<;V3Gt`kkHmMv zAB#T?ese-|%vS+<)A!Rb8s7V&cUR`Ck> zHt|aMcJV6s4)MA0o#ON0yTs?icZ)B8SBjqxuM)oyzE^x9yjuJs_&)KA;Wgsb@LKUj z@H+9u@Otqj@crUT;SJ)Kzz>LD3O^`*8N5;aa(I*Y74T;9E8#8TSHlmBUjsiPel7f{ z_%e8__;v6$@#XMi;w#|o;y1ugh~EhB5U-B1Y)=z{(<1m8@x}17;!EIN;!EM(;+MdC z#4m;SieCmlCw@8ny!aLH3*uM8FN$9Uza)M&{Id8p@GIii!mo-igZGJF2k#eO4j&L- z0ly}GJ^Z@(4e&wn8{s#^Z-U zd*XM)N5xmd$HZ5`$Hnh~-xt3Z{y=;+{Gs@L@CorX@JHfn;g7}F!Jmk)hd&j+AO1{y z1N^!81MnB(55ixHZ-l=R-voaxz8U^Td<*=o_(Sk_;wzhRzYv1cD)<@kd*Elq?}c}X zuZDMv-v{pzUjy$IUkg7cz7Bp~d_DYv`2FyU;v3+X#2XuZuqd9~6HSenWgK{HFLe_>lNx@L}=o@LS@K!$-uQfZrD10ly>u zB>b-UQ}BD@JK>|^eM>A`HX%6mgFWK?;T-V+aIW}3I8S^K>=hpj=Zg=4XNeDm3&e-P zh2q2E+2SMMIpQPXBJojhvG{1XM0^ZfDn1r26CVekCq5o77oPxEh);wo#V5g4;*;UI z;#1&x;%CG2#izmx#HYdMi%*9y5T5~GD1HvSQ2bo@BJr8<#p342$lA#dl3DOs;&!;b zxC8DW?u0vvyWmdZA#i8$P`HbD7~EAn9PTC_0mq6*!rjHA;5hMUI9|LCoFHBoP86>P zCyCdGlf@grDdG*`RPjb|ns{S4UAzgLA>I_u6mJG+i8qIPh_`@yinoM&iMN7#i?@dR zh_`|JinoRPiM!$c;xX_5@sXYd{J)rd|Mv-7M=A+3v}ESN@HQXgJVm&LP)_juf8qM= PfA%sf(pfej#`gaKJ4wTJ literal 0 HcmV?d00001 From fb02097ba785897299cc6b717b62141fc30c51e7 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 28 Jun 2023 10:07:59 +0300 Subject: [PATCH 050/164] Fix TestRandomEnvAfterMigrate --- .../test-compute-contract-v2/Cargo.lock | 104 +++++++++--------- .../test-compute-contract-v2/Cargo.toml | 6 +- .../keeper/secret_contracts_migrate_test.go | 2 - .../keeper/testdata/v1-contract-v2.wasm | Bin 1894770 -> 1892280 bytes 4 files changed, 56 insertions(+), 56 deletions(-) diff --git a/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Cargo.lock b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Cargo.lock index 11b7d58ea..a5ae4f7f4 100644 --- a/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Cargo.lock +++ b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Cargo.lock @@ -83,53 +83,14 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" -[[package]] -name = "cosmwasm-crypto" -version = "1.1.9" -source = "git+https://github.com/scrtlabs/cosmwasm?rev=46a0be1de3b3c4f45d502d31cd08c258598c54be#46a0be1de3b3c4f45d502d31cd08c258598c54be" -dependencies = [ - "digest 0.10.6", - "ed25519-zebra", - "k256", - "rand_core 0.6.4", - "thiserror", -] - [[package]] name = "cosmwasm-derive" -version = "1.1.9" -source = "git+https://github.com/scrtlabs/cosmwasm?rev=46a0be1de3b3c4f45d502d31cd08c258598c54be#46a0be1de3b3c4f45d502d31cd08c258598c54be" +version = "1.1.10" +source = "git+https://github.com/scrtlabs/cosmwasm?rev=6c639b5#6c639b5a85ef66f87d72284dc68ae051eab09007" dependencies = [ "syn 1.0.109", ] -[[package]] -name = "cosmwasm-std" -version = "1.1.9" -source = "git+https://github.com/scrtlabs/cosmwasm?rev=46a0be1de3b3c4f45d502d31cd08c258598c54be#46a0be1de3b3c4f45d502d31cd08c258598c54be" -dependencies = [ - "base64", - "cosmwasm-crypto", - "cosmwasm-derive", - "derivative", - "forward_ref", - "hex", - "schemars", - "serde", - "serde-json-wasm 0.4.1", - "thiserror", - "uint", -] - -[[package]] -name = "cosmwasm-storage" -version = "1.1.9" -source = "git+https://github.com/scrtlabs/cosmwasm?rev=46a0be1de3b3c4f45d502d31cd08c258598c54be#46a0be1de3b3c4f45d502d31cd08c258598c54be" -dependencies = [ - "cosmwasm-std", - "serde", -] - [[package]] name = "cpufeatures" version = "0.2.6" @@ -212,9 +173,9 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", "crypto-common", @@ -263,7 +224,7 @@ dependencies = [ "base16ct", "crypto-bigint", "der", - "digest 0.10.6", + "digest 0.10.7", "ff", "generic-array", "group", @@ -343,7 +304,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -361,7 +322,7 @@ dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "sha2 0.10.6", + "sha2 0.10.7", ] [[package]] @@ -498,6 +459,45 @@ dependencies = [ "cc", ] +[[package]] +name = "secret-cosmwasm-crypto" +version = "1.1.10" +source = "git+https://github.com/scrtlabs/cosmwasm?rev=6c639b5#6c639b5a85ef66f87d72284dc68ae051eab09007" +dependencies = [ + "digest 0.10.7", + "ed25519-zebra", + "k256", + "rand_core 0.6.4", + "thiserror", +] + +[[package]] +name = "secret-cosmwasm-std" +version = "1.1.10" +source = "git+https://github.com/scrtlabs/cosmwasm?rev=6c639b5#6c639b5a85ef66f87d72284dc68ae051eab09007" +dependencies = [ + "base64", + "cosmwasm-derive", + "derivative", + "forward_ref", + "hex", + "schemars", + "secret-cosmwasm-crypto", + "serde", + "serde-json-wasm 0.4.1", + "thiserror", + "uint", +] + +[[package]] +name = "secret-cosmwasm-storage" +version = "1.1.10" +source = "git+https://github.com/scrtlabs/cosmwasm?rev=6c639b5#6c639b5a85ef66f87d72284dc68ae051eab09007" +dependencies = [ + "secret-cosmwasm-std", + "serde", +] + [[package]] name = "serde" version = "1.0.159" @@ -573,13 +573,13 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -588,7 +588,7 @@ version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "rand_core 0.6.4", ] @@ -685,10 +685,10 @@ name = "v1-sanity-contract-v2" version = "0.0.1" dependencies = [ "bincode2", - "cosmwasm-std", - "cosmwasm-storage", "schemars", "secp256k1", + "secret-cosmwasm-std", + "secret-cosmwasm-storage", "serde", "serde-json-wasm 0.2.3", ] diff --git a/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Cargo.toml b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Cargo.toml index 7683e26e7..866de30ac 100644 --- a/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Cargo.toml +++ b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Cargo.toml @@ -31,8 +31,10 @@ backtraces = ["cosmwasm-std/backtraces"] with_floats = [] [dependencies] -cosmwasm-std = { git = "https://github.com/scrtlabs/cosmwasm", rev = "46a0be1de3b3c4f45d502d31cd08c258598c54be", package = "cosmwasm-std" } -cosmwasm-storage = { git = "https://github.com/scrtlabs/cosmwasm", rev = "46a0be1de3b3c4f45d502d31cd08c258598c54be", package = "cosmwasm-storage" } +cosmwasm-std = { git = "https://github.com/scrtlabs/cosmwasm", rev = "6c639b5", package = "secret-cosmwasm-std", features = [ + "random" +] } +cosmwasm-storage = { git = "https://github.com/scrtlabs/cosmwasm", rev = "6c639b5", package = "secret-cosmwasm-storage" } schemars = "0.8.1" serde = { version = "1.0.114", default-features = false, features = [ "derive", diff --git a/x/compute/internal/keeper/secret_contracts_migrate_test.go b/x/compute/internal/keeper/secret_contracts_migrate_test.go index 574531fd3..c53a12a55 100644 --- a/x/compute/internal/keeper/secret_contracts_migrate_test.go +++ b/x/compute/internal/keeper/secret_contracts_migrate_test.go @@ -175,8 +175,6 @@ func TestAddrValidateFunctionAfterMigrate(t *testing.T) { } func TestRandomEnvAfterMigrate(t *testing.T) { - t.SkipNow() // TODO this shuold work... - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) diff --git a/x/compute/internal/keeper/testdata/v1-contract-v2.wasm b/x/compute/internal/keeper/testdata/v1-contract-v2.wasm index 27373cab84e6096be1fd52feb1209c4615ec96ff..df33435ab366e49208959c04714a337ca3c24d3b 100755 GIT binary patch delta 187907 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�Z|f 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
    2C7~A+@>={q7VMM4-!?<4sO_u@Ws9gXV$AU1R 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 mJwGqfzfu;qOaeE^)WYb}TY@Liu@N&;J7g{=NeM From 1f85986dcc1beb99ef9bc7aecca7b0aeba16e87e Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Fri, 30 Jun 2023 15:27:26 +0300 Subject: [PATCH 055/164] Change a println!() to a trace!() --- .../enclaves/shared/contract-engine/src/contract_validation.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index 5d51bdccd..5a13904a5 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -207,7 +207,7 @@ pub fn validate_contract_key( )?; if base_env.was_migrated() { - println!("Contract was migrated, validating proof"); + trace!("Contract was migrated, validating proof"); let og_contract_key: [u8; CONTRACT_KEY_LENGTH] = base_env.get_og_contract_key()?; let sent_contract_key_proof = base_env.get_current_contract_key_proof()?; From 38231a23942f3864568d9af277a48ab7e00ad532 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Fri, 30 Jun 2023 15:35:30 +0300 Subject: [PATCH 056/164] Copy all exec tests and modify to test migrate --- .../keeper/secret_contracts_migrate_test.go | 1892 +++++++++++++++-- .../keeper/secret_contracts_utils_test.go | 156 +- 2 files changed, 1818 insertions(+), 230 deletions(-) diff --git a/x/compute/internal/keeper/secret_contracts_migrate_test.go b/x/compute/internal/keeper/secret_contracts_migrate_test.go index c53a12a55..88fc9d963 100644 --- a/x/compute/internal/keeper/secret_contracts_migrate_test.go +++ b/x/compute/internal/keeper/secret_contracts_migrate_test.go @@ -80,18 +80,18 @@ func TestWithStorageAfterMigrate(t *testing.T) { require.Empty(t, data) } -func TestContractFromDifferentAccountAfterMigrate(t *testing.T) { +func TestMigrateContractFromNonAdminAccount(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, WalletB, privKeyB := setupTest(t, TestContractPaths[migrateContractV1], sdk.NewCoins()) newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[migrateContractV2], walletA) _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"Nop":{}}`, true, true, defaultGasForTests) - _, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, WalletB, privKeyB, `{"migrate":{}}`, false, true, math.MaxUint64) - require.NotNil(t, err) + _, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, WalletB, privKeyB, `{"migrate":{}}`, false, true, math.MaxUint64, 0) + require.Contains(t, err.Error(), "requires migrate from admin: migrate contract failed") } -func TestVmErrorAfterMigrate(t *testing.T) { +func TestVmErrorDuringMigrate(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[migrateContractV1], sdk.NewCoins()) newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[migrateContractV2], walletA) @@ -117,7 +117,7 @@ func TestStdErrorAfterMigrate(t *testing.T) { require.Equal(t, err.Error(), "encrypted: Generic error: this is an std error") } -/// copy of exec tests but with a migrate twist: +/// copy of exec tests but doing it after a migration: func TestStateAfterMigrate(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) @@ -174,7 +174,7 @@ func TestAddrValidateFunctionAfterMigrate(t *testing.T) { require.Equal(t, string(data), "\"Apple\"") } -func TestRandomEnvAfterMigrate(t *testing.T) { +func TestEnvAfterMigrate(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) @@ -219,98 +219,6 @@ func TestRandomEnvAfterMigrate(t *testing.T) { ) } -func TestEnvAfterMigrate(t *testing.T) { - type ReturnedV1MessageInfo struct { - Sender cosmwasm.HumanAddress `json:"sender"` - SentFunds cosmwasm.Coins `json:"funds"` - // Random string `json:"random"` - } - - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - - _, _, contractAddress, initEvents, initErr := initHelperImpl(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"get_env":{}}`, true, true, defaultGasForTests, -1, sdk.NewCoins(sdk.NewInt64Coin("denom", 1))) - require.Empty(t, initErr) - require.Len(t, initEvents, 1) - - newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) - _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) - require.Empty(t, migrateErr) - - expectedV1Env := fmt.Sprintf( - `{"block":{"height":%d,"time":"%d","chain_id":"%s"},"transaction":null,"contract":{"address":"%s","code_hash":"%s"}}`, - ctx.BlockHeight(), - // env.block.time is nanoseconds since unix epoch - ctx.BlockTime().UnixNano(), - ctx.ChainID(), - contractAddress.String(), - calcCodeHash(TestContractPaths[v1MigratedContract]), - ) - - _, _, _, execEvents, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"get_env":{}}`, true, true, defaultGasForTests, 1) - require.Empty(t, execErr) - - if true { - requireEventsInclude(t, - execEvents, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - { - Key: "env", - Value: expectedV1Env, - }, - }, - }, - ) - - execEvent := execEvents[0] - infoLogAttributeIndex := slices.IndexFunc(execEvent, func(c v010types.LogAttribute) bool { return c.Key == "info" }) - infoLogAttribute := execEvent[infoLogAttributeIndex] - - var actualMessageInfo ReturnedV1MessageInfo - _ = json.Unmarshal([]byte(infoLogAttribute.Value), &actualMessageInfo) - - require.Equal(t, walletA.String(), actualMessageInfo.Sender) - require.Equal(t, cosmwasm.Coins{{Denom: "denom", Amount: "1"}}, actualMessageInfo.SentFunds) - - // disabling random tests - // require.Len(t, actualMessageInfo.Random, 44) - // require.NotEqual(t, firstRandom, actualMessageInfo.Random) - } else { - requireEvents(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - { - Key: "env", - Value: fmt.Sprintf( - `{"block":{"height":%d,"time":%d,"chain_id":"%s"},"message":{"sender":"%s","sent_funds":[{"denom":"denom","amount":"1"}]},"contract":{"address":"%s"},"contract_key":null,"contract_code_hash":"%s"}`, - ctx.BlockHeight(), - // env.block.time is seconds since unix epoch - ctx.BlockTime().Unix(), - ctx.ChainID(), - walletA.String(), - contractAddress.String(), - calcCodeHash(TestContractPaths[v1MigratedContract]), - ), - }, - }, - }, - execEvents, - ) - } - - if true { - // only env (no msg info) in v1 query - queryRes, qErr := queryHelper(t, keeper, ctx, contractAddress, `{"get_env":{}}`, true, false, math.MaxUint64) - require.Empty(t, qErr) - - require.Equal(t, expectedV1Env, queryRes) - } else { - // no env or msg info in v0.10 query - } -} - func TestNestedAttributeAfterMigrate(t *testing.T) { // For more reference: https://github.com/scrtlabs/SecretNetwork/issues/1235 ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) @@ -899,24 +807,20 @@ func TestEd25519SignAfterMigrate(t *testing.T) { } func TestSleepAfterMigrate(t *testing.T) { - for _, testContract := range testContracts { - t.Run(testContract.CosmWasmVersion, func(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) - require.Empty(t, initErr) + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) - newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) - _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) - require.Empty(t, migrateErr) + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) - _, _, _, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"sleep":{"ms":3000}}`, false, true, defaultGasForTests, 0) + _, _, _, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"sleep":{"ms":3000}}`, false, true, defaultGasForTests, 0) - require.Error(t, execErr) - require.Error(t, execErr.GenericErr) - require.Contains(t, execErr.GenericErr.Msg, "the contract panicked") - }) - } + require.Error(t, execErr) + require.Error(t, execErr.GenericErr) + require.Contains(t, execErr.GenericErr.Msg, "the contract panicked") } func TestAllocateOnHeapFailBecauseMemoryLimitAfterMigrate(t *testing.T) { @@ -929,9 +833,9 @@ func TestAllocateOnHeapFailBecauseMemoryLimitAfterMigrate(t *testing.T) { _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) require.Empty(t, migrateErr) - _, _, data, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"allocate_on_heap":{"bytes":13631488}}`, false, true, defaultGasForTests, 0) + _, _, data, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"allocate_on_heap":{"bytes":12582913}}`, false, true, defaultGasForTests, 0) - // this should fail with memory error because 13MiB is more than the allowed 12MiB + // this should fail with memory error because 12MiB+1 is more than the allowed 12MiB require.Empty(t, data) @@ -970,25 +874,25 @@ func TestAllocateOnHeapFailBecauseGasLimitAfterMigrate(t *testing.T) { } func TestAllocateOnHeapMoreThanSGXHasFailBecauseMemoryLimitAfterMigrate(t *testing.T) { - for _, testContract := range testContracts { - t.Run(testContract.CosmWasmVersion, func(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) - require.Empty(t, initErr) + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) - _, _, data, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"allocate_on_heap":{"bytes":1073741824}}`, false, true, 9_000_000, 0) + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, addr, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) - // this should fail with memory error because 1GiB is more - // than the allowed 12MiB, gas is 9mn so WASM gas is 900mn - // which is bigger than the 134mn from the previous test + _, _, data, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"allocate_on_heap":{"bytes":1073741824}}`, false, true, 9_000_000, 0) - require.Empty(t, data) + // this should fail with memory error because 1GiB is more + // than the allowed 12MiB, gas is 9mn so WASM gas is 900mn + // which is bigger than the 134mn from the previous test - require.NotNil(t, execErr.GenericErr) - require.Contains(t, execErr.GenericErr.Msg, "the contract panicked") - }) - } + require.Empty(t, data) + + require.NotNil(t, execErr.GenericErr) + require.Contains(t, execErr.GenericErr.Msg, "the contract panicked") } func TestPassNullPointerToImportsAfterMigrate(t *testing.T) { @@ -1015,11 +919,7 @@ func TestPassNullPointerToImportsAfterMigrate(t *testing.T) { _, _, _, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"pass_null_pointer_to_imports_should_throw":{"pass_type":"%s"}}`, passType), false, true, defaultGasForTests, 0) require.NotNil(t, execErr.GenericErr) - if true { - require.Contains(t, execErr.GenericErr.Msg, "execute contract failed") - } else { - require.Contains(t, execErr.GenericErr.Msg, "failed to read memory") - } + require.Contains(t, execErr.GenericErr.Msg, "execute contract failed") }) } } @@ -1657,32 +1557,28 @@ func TestGasIsChargedForExecCallbackToExecAfterMigrate(t *testing.T) { } func TestMsgSenderInCallbackAfterMigrate(t *testing.T) { - for _, testContract := range testContracts { - t.Run(testContract.CosmWasmVersion, func(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) - require.Empty(t, err) + _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) - newCodeId, newCodeHash := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) - _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, addr, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) - require.Empty(t, migrateErr) + newCodeId, newCodeHash := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, addr, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) - _, _, _, events, _, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"callback_to_log_msg_sender":{"to":"%s","code_hash":"%s"}}`, addr.String(), newCodeHash), true, true, defaultGasForTests, 0) + _, _, _, events, _, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"callback_to_log_msg_sender":{"to":"%s","code_hash":"%s"}}`, addr.String(), newCodeHash), true, true, defaultGasForTests, 0) - require.Empty(t, err) - requireEvents(t, []ContractEvent{ - { - {Key: "contract_address", Value: addr.String()}, - {Key: "hi", Value: "hey"}, - }, - { - {Key: "contract_address", Value: addr.String()}, - {Key: "msg.sender", Value: addr.String()}, - }, - }, events) - }) - } + require.Empty(t, err) + requireEvents(t, []ContractEvent{ + { + {Key: "contract_address", Value: addr.String()}, + {Key: "hi", Value: "hey"}, + }, + { + {Key: "contract_address", Value: addr.String()}, + {Key: "msg.sender", Value: addr.String()}, + }, + }, events) } func TestDepositToContractAfterMigrate(t *testing.T) { @@ -1783,47 +1679,43 @@ func TestContractSendFundsToExecCallbackAfterMigrate(t *testing.T) { } func TestContractSendFundsToExecCallbackNotEnoughAfterMigrate(t *testing.T) { - for _, testContract := range testContracts { - t.Run(testContract.CosmWasmVersion, func(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) - require.Empty(t, initErr) + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) - newCodeId, newCodeHash := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) - _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, addr, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) - require.Empty(t, migrateErr) + newCodeId, newCodeHash := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, addr, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) - _, _, addr2, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) - require.Empty(t, initErr) + _, _, addr2, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) - _, migrateErr = migrateHelper(t, keeper, ctx, newCodeId, addr2, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) - require.Empty(t, migrateErr) + _, migrateErr = migrateHelper(t, keeper, ctx, newCodeId, addr2, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) - contractCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr) - contract2CoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr2) - walletCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletA) + contractCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr) + contract2CoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr2) + walletCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletA) - require.Equal(t, "", contractCoinsBefore.String()) - require.Equal(t, "", contract2CoinsBefore.String()) - require.Equal(t, "200000denom", walletCoinsBefore.String()) + require.Equal(t, "", contractCoinsBefore.String()) + require.Equal(t, "", contract2CoinsBefore.String()) + require.Equal(t, "200000denom", walletCoinsBefore.String()) - _, _, _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_funds_to_exec_callback":{"to":"%s","denom":"%s","amount":%d,"code_hash":"%s"}}`, addr2.String(), "denom", 19, newCodeHash), false, true, defaultGasForTests, 17) + _, _, _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_funds_to_exec_callback":{"to":"%s","denom":"%s","amount":%d,"code_hash":"%s"}}`, addr2.String(), "denom", 19, newCodeHash), false, true, defaultGasForTests, 17) - require.NotNil(t, execErr.GenericErr) - require.Contains(t, execErr.GenericErr.Msg, "insufficient funds") + require.NotNil(t, execErr.GenericErr) + require.Contains(t, execErr.GenericErr.Msg, "insufficient funds") - contractCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr) - contract2CoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr2) - walletCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletA) + contractCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr) + contract2CoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr2) + walletCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletA) - // The state here should have been reverted by the APP but in go-tests we create our own keeper - // so it is not reverted in this case. - require.Equal(t, "17denom", contractCoinsAfter.String()) - require.Equal(t, "", contract2CoinsAfter.String()) - require.Equal(t, "199983denom", walletCoinsAfter.String()) - }) - } + // The state here should have been reverted by the APP but in go-tests we create our own keeper + // so it is not reverted in this case. + require.Equal(t, "17denom", contractCoinsAfter.String()) + require.Equal(t, "", contract2CoinsAfter.String()) + require.Equal(t, "199983denom", walletCoinsAfter.String()) } func TestExecCallbackContractErrorAfterMigrate(t *testing.T) { @@ -1999,23 +1891,19 @@ func TestExecContractErrorAfterMigrate(t *testing.T) { } func TestExecPanicAfterMigrate(t *testing.T) { - for _, testContract := range testContracts { - t.Run(testContract.CosmWasmVersion, func(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) - require.Empty(t, initErr) + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) - newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) - _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, addr, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) - require.Empty(t, migrateErr) + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, addr, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) - _, _, _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"panic":{}}`, false, true, defaultGasForTests, 0) + _, _, _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"panic":{}}`, false, true, defaultGasForTests, 0) - require.NotNil(t, execErr.GenericErr) - require.Contains(t, execErr.GenericErr.Msg, "the contract panicked") - }) - } + require.NotNil(t, execErr.GenericErr) + require.Contains(t, execErr.GenericErr.Msg, "the contract panicked") } func TestCanonicalizeAddressErrorsAfterMigrate(t *testing.T) { @@ -2629,3 +2517,1609 @@ func TestIBCHooksOutgoingTransferTimeoutAfterMigrate(t *testing.T) { }) } } + +/// copy of exec tests but doing it during a migration: + +func TestStateDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + _, _, _, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"set_state":{"key":"banana","value":"🍌"}}`, true, true, defaultGasForTests, 0) + require.Empty(t, execErr) + + _, _, data, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"get_state":{"key":"banana"}}`, true, true, defaultGasForTests, 0) + require.Empty(t, execErr) + require.Equal(t, "🍌", string(data)) + + _, _, _, _, _, execErr = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"remove_state":{"key":"banana"}}`, true, true, defaultGasForTests, 0) + require.Empty(t, execErr) + + _, _, data, _, _, execErr = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"get_state":{"key":"banana"}}`, true, true, defaultGasForTests, 0) + require.Empty(t, execErr) + require.Empty(t, data) + + _, _, _, _, _, execErr = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"set_state":{"key":"banana","value":"🍌"}}`, true, true, defaultGasForTests, 0) + require.Empty(t, execErr) + + _, _, data, _, _, execErr = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"get_state":{"key":"banana"}}`, true, true, defaultGasForTests, 0) + require.Empty(t, execErr) + require.Equal(t, "🍌", string(data)) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + + migrateResult, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"get_state":{"key":"banana"}}`, true, true, math.MaxUint64) + require.Empty(t, err) + require.Equal(t, "🍌", string(migrateResult.Data)) + + migrateResult, err = migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"set_state":{"key":"banana","value":"🍌"}}`, true, true, defaultGasForTests) + require.Empty(t, execErr) + + migrateResult, err = migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"get_state":{"key":"banana"}}`, true, true, defaultGasForTests) + require.Empty(t, execErr) + require.Equal(t, "🍌", string(migrateResult.Data)) + + migrateResult, err = migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"remove_state":{"key":"banana"}}`, true, true, defaultGasForTests) + require.Empty(t, execErr) + + migrateResult, err = migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"get_state":{"key":"banana"}}`, true, true, defaultGasForTests) + require.Empty(t, execErr) + require.Empty(t, string(migrateResult.Data)) + + migrateResult, err = migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"set_state":{"key":"banana","value":"🍌"}}`, true, true, defaultGasForTests) + require.Empty(t, execErr) + + migrateResult, err = migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"get_state":{"key":"banana"}}`, true, true, defaultGasForTests) + require.Empty(t, execErr) + require.Equal(t, "🍌", string(migrateResult.Data)) + + _, _, data, _, _, execErr = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"get_state":{"key":"banana"}}`, true, true, defaultGasForTests, 0) + require.Empty(t, execErr) + require.Equal(t, "🍌", string(data)) +} + +func TestAddrValidateFunctionDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + + migrateResult, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"validate_address":{"addr":"%s"}}`, contractAddress), true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + resp, aErr := sdk.AccAddressFromBech32(string(migrateResult.Data)) + require.Empty(t, aErr) + require.Equal(t, resp, contractAddress) + + migrateResult, migrateErr = migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"validate_address":{"addr":"secret18vd8fpwxzck93qlwghaj6arh4p7c5nyf7hmag8"}}`), true, true, math.MaxUint64) + require.Empty(t, migrateErr) + require.Equal(t, string(migrateResult.Data), "\"Apple\"") +} + +func TestEnvDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + migrateResult, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"get_env":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + migrateEvent := migrateResult.WasmEvents[0] + envAttributeIndex := slices.IndexFunc(migrateEvent, func(c v010types.LogAttribute) bool { return c.Key == "env" }) + envAttribute := migrateEvent[envAttributeIndex] + + var actualMigrateEnv cosmwasm.Env + json.Unmarshal([]byte(envAttribute.Value), &actualMigrateEnv) + + expectedV1EnvMigrate := fmt.Sprintf( + `{"block":{"height":%d,"time":"%d","chain_id":"%s","random":"%s"},"transaction":null,"contract":{"address":"%s","code_hash":"%s"}}`, + ctx.BlockHeight(), + // env.block.time is nanoseconds since unix epoch + ctx.BlockTime().UnixNano(), + ctx.ChainID(), + base64.StdEncoding.EncodeToString(actualMigrateEnv.Block.Random), + contractAddress.String(), + calcCodeHash(TestContractPaths[v1MigratedContract]), + ) + + requireEventsInclude(t, + migrateResult.WasmEvents, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + { + Key: "env", + Value: expectedV1EnvMigrate, + }, + }, + }, + ) +} + +func TestNestedAttributeDuringMigrate(t *testing.T) { + // For more reference: https://github.com/scrtlabs/SecretNetwork/issues/1235 + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + migrateResult, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"add_attribute_step1":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🦄"}, + }, + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr2", Value: "🦄"}, + }, + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr3", Value: "🦄"}, + }, + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr4", Value: "🦄"}, + }, + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr_reply", Value: "🦄"}, + }, + }, + migrateResult.WasmEvents, + ) + + require.Equal(t, string(migrateResult.Data), "\"reply\"") +} + +func TestEmptyLogKeyValueDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + migrateResult, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"empty_log_key_value":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "my value is empty", Value: ""}, + {Key: "", Value: "my key is empty"}, + }, + }, + migrateResult.WasmEvents, + ) +} + +func TestExecNoLogsDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + migrateResult, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"no_logs":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + }, + }, + migrateResult.WasmEvents, + ) +} + +func TestEmptyDataDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + migrateResult, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"empty_data":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + require.Empty(t, migrateResult.Data) +} + +func TestNoDataDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + migrateResult, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"no_data":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + require.Empty(t, migrateResult.Data) +} + +func TestUnicodeDataDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + migrateResult, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"unicode_data":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + require.Equal(t, "🍆🥑🍄", string(migrateResult.Data)) +} + +func TestSecp256k1VerifyDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + + // https://paulmillr.com/noble/ + + t.Run("CorrectCompactPubkey", func(t *testing.T) { + res, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"A0ZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo//","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, true, math.MaxUint64) + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + res.WasmEvents, + ) + }) + t.Run("CorrectLongPubkey", func(t *testing.T) { + res, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"BEZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo///ne03QpL+5WFHztzVceB3WD4QY/Ipl0UkHr/R8kDpVk=","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, true, defaultGasForTests) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + res.WasmEvents, + ) + }) + t.Run("IncorrectMsgHashCompactPubkey", func(t *testing.T) { + res, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"A0ZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo//","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzas="}}`, true, true, defaultGasForTests) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + res.WasmEvents, + ) + }) + t.Run("IncorrectMsgHashLongPubkey", func(t *testing.T) { + res, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"BEZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo///ne03QpL+5WFHztzVceB3WD4QY/Ipl0UkHr/R8kDpVk=","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzas="}}`, true, true, defaultGasForTests) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + res.WasmEvents, + ) + }) + t.Run("IncorrectSigCompactPubkey", func(t *testing.T) { + res, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"A0ZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo//","sig":"rhZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, true, defaultGasForTests) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + res.WasmEvents, + ) + }) + t.Run("IncorrectSigLongPubkey", func(t *testing.T) { + res, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"BEZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo///ne03QpL+5WFHztzVceB3WD4QY/Ipl0UkHr/R8kDpVk=","sig":"rhZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, true, defaultGasForTests) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + res.WasmEvents, + ) + }) + t.Run("IncorrectCompactPubkey", func(t *testing.T) { + res, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"AoSdDHH9J0Bfb9pT8GFn+bW9cEVkgIh4bFsepMWmczXc","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, true, defaultGasForTests) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + res.WasmEvents, + ) + }) + t.Run("IncorrectLongPubkey", func(t *testing.T) { + res, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"BISdDHH9J0Bfb9pT8GFn+bW9cEVkgIh4bFsepMWmczXcFWl11YCgu65hzvNDQE2Qo1hwTMQ/42Xif8O/MrxzvxI=","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, true, defaultGasForTests) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + res.WasmEvents, + ) + }) +} + +func TestEd25519VerifyDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + + // https://paulmillr.com/noble/ + t.Run("Correct", func(t *testing.T) { + res, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"ed25519_verify":{"iterations":1,"pubkey":"LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","sig":"8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","msg":"YXNzYWYgd2FzIGhlcmU="}}`, true, true, defaultGasForTests) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + res.WasmEvents, + ) + }) + t.Run("IncorrectMsg", func(t *testing.T) { + res, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"ed25519_verify":{"iterations":1,"pubkey":"LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","sig":"8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","msg":"YXNzYWYgd2FzIGhlcmUK"}}`, true, true, defaultGasForTests) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + res.WasmEvents, + ) + }) + t.Run("IncorrectSig", func(t *testing.T) { + res, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"ed25519_verify":{"iterations":1,"pubkey":"LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","sig":"8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDw==","msg":"YXNzYWYgd2FzIGhlcmU="}}`, true, true, defaultGasForTests) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + res.WasmEvents, + ) + }) + t.Run("IncorrectPubkey", func(t *testing.T) { + res, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"ed25519_verify":{"iterations":1,"pubkey":"DV1lgRdKw7nt4hvl8XkGZXMzU9S3uM9NLTK0h0qMbUs=","sig":"8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","msg":"YXNzYWYgd2FzIGhlcmU="}}`, true, true, defaultGasForTests) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + res.WasmEvents, + ) + }) +} + +func TestEd25519BatchVerifyDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + + // https://paulmillr.com/noble/ + t.Run("Correct", func(t *testing.T) { + res, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg=="],"msgs":["YXNzYWYgd2FzIGhlcmU="]}}`, true, true, defaultGasForTests) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + res.WasmEvents, + ) + }) + t.Run("100Correct", func(t *testing.T) { + res, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg=="],"msgs":["YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU="]}}`, true, true, defaultGasForTests) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + res.WasmEvents, + ) + }) + t.Run("IncorrectPubkey", func(t *testing.T) { + res, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["DV1lgRdKw7nt4hvl8XkGZXMzU9S3uM9NLTK0h0qMbUs="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg=="],"msgs":["YXNzYWYgd2FzIGhlcmU="]}}`, true, true, defaultGasForTests) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + res.WasmEvents, + ) + }) + t.Run("IncorrectMsg", func(t *testing.T) { + res, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg=="],"msgs":["YXNzYWYgd2FzIGhlcmUK"]}}`, true, true, defaultGasForTests) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + res.WasmEvents, + ) + }) + t.Run("IncorrectSig", func(t *testing.T) { + res, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDw=="],"msgs":["YXNzYWYgd2FzIGhlcmU="]}}`, true, true, defaultGasForTests) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + res.WasmEvents, + ) + }) + t.Run("CorrectEmptySigsEmptyMsgsOnePubkey", func(t *testing.T) { + res, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA="],"sigs":[],"msgs":[]}}`, true, true, defaultGasForTests) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + res.WasmEvents, + ) + }) + t.Run("CorrectEmpty", func(t *testing.T) { + res, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":[],"sigs":[],"msgs":[]}}`, true, true, defaultGasForTests) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + res.WasmEvents, + ) + }) + t.Run("CorrectEmptyPubkeysEmptySigsOneMsg", func(t *testing.T) { + res, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":[],"sigs":[],"msgs":["YXNzYWYgd2FzIGhlcmUK"]}}`, true, true, defaultGasForTests) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + res.WasmEvents, + ) + }) + t.Run("CorrectMultisig", func(t *testing.T) { + res, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","2ukhmWRNmcgCrB9fpLP9/HZVuJn6AhpITf455F4GsbM="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","bp/N4Ub2WFk9SE9poZVEanU1l46WMrFkTd5wQIXi6QJKjvZUi7+GTzmTe8y2yzgpBI+GWQmt0/QwYbnSVxq/Cg=="],"msgs":["YXNzYWYgd2FzIGhlcmU="]}}`, true, true, defaultGasForTests) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + res.WasmEvents, + ) + }) + t.Run("CorrectMultiMsgOneSigner", func(t *testing.T) { + res, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["2ukhmWRNmcgCrB9fpLP9/HZVuJn6AhpITf455F4GsbM="],"sigs":["bp/N4Ub2WFk9SE9poZVEanU1l46WMrFkTd5wQIXi6QJKjvZUi7+GTzmTe8y2yzgpBI+GWQmt0/QwYbnSVxq/Cg==","uuNxLEzAYDbuJ+BiYN94pTqhD7UhvCJNbxAbnWz0B9DivkPXmqIULko0DddP2/tVXPtjJ90J20faiWCEC3QkDg=="],"msgs":["YXNzYWYgd2FzIGhlcmU=","cGVhY2Ugb3V0"]}}`, true, true, defaultGasForTests) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + res.WasmEvents, + ) + }) +} + +func TestSecp256k1RecoverPubkeyDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + + // https://paulmillr.com/noble/ + res, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"secp256k1_recover_pubkey":{"iterations":1,"recovery_param":0,"sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, true, defaultGasForTests) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "A0ZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo//"}, + }, + }, + res.WasmEvents, + ) + + res, err = migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"secp256k1_recover_pubkey":{"iterations":1,"recovery_param":1,"sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, true, defaultGasForTests) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "Ams198xOCEVnc/ESvxF2nxnE3AVFO8ahB22S1ZgX2vSR"}, + }, + }, + res.WasmEvents, + ) +} + +func TestSecp256k1SignDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + + // priv iadRiuRKNZvAXwolxqzJvr60uiMDJTxOEzEwV8OK2ao= + // pub ArQojoh5TVlSSNA1HFlH5HcQsv0jnrpeE7hgwR/N46nS + // msg d2VuIG1vb24= + // msg_hash K9vGEuzCYCUcIXlhMZu20ke2K4mJhreguYct5MqAzhA= + + // https://paulmillr.com/noble/ + res, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"secp256k1_sign":{"iterations":1,"msg":"d2VuIG1vb24=","privkey":"iadRiuRKNZvAXwolxqzJvr60uiMDJTxOEzEwV8OK2ao="}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + signature := res.WasmEvents[0][1].Value + + res, err = migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"secp256k1_verify":{"iterations":1,"pubkey":"ArQojoh5TVlSSNA1HFlH5HcQsv0jnrpeE7hgwR/N46nS","sig":"%s","msg_hash":"K9vGEuzCYCUcIXlhMZu20ke2K4mJhreguYct5MqAzhA="}}`, signature), true, true, defaultGasForTests) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + res.WasmEvents, + ) +} + +func TestEd25519SignDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + + // priv z01UNefH2yjRslwZMmcHssdHmdEjzVvbxjr+MloUEYo= + // pub jh58UkC0FDsiupZBLdaqKUqYubJbk3LDaruZiJiy0Po= + // msg d2VuIG1vb24= + // msg_hash K9vGEuzCYCUcIXlhMZu20ke2K4mJhreguYct5MqAzhA= + + // https://paulmillr.com/noble/ + res, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"ed25519_sign":{"iterations":1,"msg":"d2VuIG1vb24=","privkey":"z01UNefH2yjRslwZMmcHssdHmdEjzVvbxjr+MloUEYo="}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + signature := res.WasmEvents[0][1].Value + + res, err = migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"ed25519_verify":{"iterations":1,"pubkey":"jh58UkC0FDsiupZBLdaqKUqYubJbk3LDaruZiJiy0Po=","sig":"%s","msg":"d2VuIG1vb24="}}`, signature), true, true, defaultGasForTests) + + require.Empty(t, err) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + res.WasmEvents, + ) +} + +func TestSleepDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + + _, execErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"sleep":{"ms":3000}}`, false, true, defaultGasForTests) + + require.Error(t, execErr) + require.Error(t, execErr.CosmWasm.GenericErr) + require.Contains(t, execErr.CosmWasm.GenericErr.Msg, "the contract panicked") +} + +func TestAllocateOnHeapFailBecauseMemoryLimitDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + + res, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"allocate_on_heap":{"bytes":12582913}}`, false, true, defaultGasForTests) + + // this should fail with memory error because 12MiB+1 is more than the allowed 12MiB + + require.Empty(t, res.Data) + + require.NotNil(t, err.CosmWasm.GenericErr) + require.Contains(t, err.CosmWasm.GenericErr.Msg, "the contract panicked") +} + +func TestAllocateOnHeapFailBecauseGasLimitDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + + // ensure we get an out of gas panic + defer func() { + r := recover() + require.NotNil(t, r) + _, ok := r.(sdk.ErrorOutOfGas) + require.True(t, ok, "%+v", r) + }() + + _, _ = migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"allocate_on_heap":{"bytes":1073741824}}`, false, true, 100_000) + + // this should fail with out of gas because 1GiB will ask for + // 134,217,728 gas units (8192 per page times 16,384 pages) + // the default gas limit in ctx is 200,000 which translates into + // 20,000,000 WASM gas units, so before the memory_grow opcode is reached + // the gas metering sees a request that'll cost 134mn and the limit + // is 20mn, so it throws an out of gas exception + + require.True(t, false) +} + +func TestAllocateOnHeapMoreThanSGXHasFailBecauseMemoryLimitDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + + res, execErr := migrateHelper(t, keeper, ctx, newCodeId, addr, walletA, privKeyA, `{"allocate_on_heap":{"bytes":1073741824}}`, false, true, 9_000_000) + + // this should fail with memory error because 1GiB is more + // than the allowed 12MiB, gas is 9mn so WASM gas is 900mn + // which is bigger than the 134mn from the previous test + + require.Empty(t, res.Data) + + require.NotNil(t, execErr.CosmWasm.GenericErr) + require.Contains(t, execErr.CosmWasm.GenericErr.Msg, "the contract panicked") +} + +func TestPassNullPointerToImportsDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + + tests := []string{ + "read_db_key", + "write_db_key", + "write_db_value", + "remove_db_key", + "canonicalize_address_input", + "humanize_address_input", + } + + for _, passType := range tests { + t.Run(passType, func(t *testing.T) { + _, execErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"pass_null_pointer_to_imports_should_throw":{"pass_type":"%s"}}`, passType), false, true, defaultGasForTests) + + require.NotNil(t, execErr.CosmWasm.GenericErr) + require.Contains(t, execErr.CosmWasm.GenericErr.Msg, "migrate contract failed") + }) + } +} + +func TestV1ReplyLoopDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + + res, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"sub_msg_loop":{"iter": 10}}`, true, true, math.MaxUint64) + + require.Empty(t, err) + require.Equal(t, uint32(20), binary.BigEndian.Uint32(res.Data)) +} + +func TestBankMsgSendDuringMigrate(t *testing.T) { + for _, test := range []struct { + description string + input string + isSuccuss bool + errorMsg string + balancesBefore string + balancesAfter string + }{ + { + description: "regular", + input: `[{"amount":"2","denom":"denom"}]`, + isSuccuss: true, + balancesBefore: "5000assaf,200000denom 5000assaf,5000denom", + balancesAfter: "4998assaf,199998denom 5000assaf,5002denom", + }, + { + description: "multi-coin", + input: `[{"amount":"1","denom":"assaf"},{"amount":"1","denom":"denom"}]`, + isSuccuss: true, + balancesBefore: "5000assaf,200000denom 5000assaf,5000denom", + balancesAfter: "4998assaf,199998denom 5001assaf,5001denom", + }, + { + description: "zero", + input: `[{"amount":"0","denom":"denom"}]`, + isSuccuss: false, + errorMsg: "encrypted: dispatch: submessages: 0denom: invalid coins", + balancesBefore: "5000assaf,200000denom 5000assaf,5000denom", + balancesAfter: "4998assaf,199998denom 5000assaf,5000denom", + }, + { + description: "insufficient funds", + input: `[{"amount":"3","denom":"denom"}]`, + isSuccuss: false, + balancesBefore: "5000assaf,200000denom 5000assaf,5000denom", + balancesAfter: "4998assaf,199998denom 5000assaf,5000denom", + errorMsg: "encrypted: dispatch: submessages: 2denom is smaller than 3denom: insufficient funds", + }, + { + description: "non-existing denom", + input: `[{"amount":"1","denom":"blabla"}]`, + isSuccuss: false, + balancesBefore: "5000assaf,200000denom 5000assaf,5000denom", + balancesAfter: "4998assaf,199998denom 5000assaf,5000denom", + errorMsg: "encrypted: dispatch: submessages: 0blabla is smaller than 1blabla: insufficient funds", + }, + { + description: "none", + input: `[]`, + isSuccuss: true, + balancesBefore: "5000assaf,200000denom 5000assaf,5000denom", + balancesAfter: "4998assaf,199998denom 5000assaf,5000denom", + }, + } { + t.Run(test.description, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, walletB, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins(sdk.NewInt64Coin("assaf", 5000))) + + walletACoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletA) + walletBCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletB) + + require.Equal(t, test.balancesBefore, walletACoinsBefore.String()+" "+walletBCoinsBefore.String()) + + var contractAddress sdk.AccAddress + + _, _, contractAddress, _, _ = initHelperImpl(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, false, true, defaultGasForTests, -1, sdk.NewCoins(sdk.NewInt64Coin("denom", 2), sdk.NewInt64Coin("assaf", 2))) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"bank_msg_send":{"to":"%s","amount":%s}}`, walletB.String(), test.input), false, true, math.MaxUint64) + + if test.isSuccuss { + require.Empty(t, migrateErr) + } else { + require.NotEmpty(t, migrateErr) + require.Equal(t, migrateErr.Error(), test.errorMsg) + } + + walletACoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletA) + walletBCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletB) + + require.Equal(t, test.balancesAfter, walletACoinsAfter.String()+" "+walletBCoinsAfter.String()) + }) + } +} + +func TestWasmMsgStructureDuringMigrate(t *testing.T) { + for _, from := range testContracts { + t.Run(fmt.Sprintf("from %s", from.CosmWasmVersion), func(t *testing.T) { + for _, to := range testContracts { + t.Run(fmt.Sprintf("to %s", to.CosmWasmVersion), func(t *testing.T) { + for _, firstCallType := range []string{"init", "exec"} { + t.Run(fmt.Sprintf("first call %s", firstCallType), func(t *testing.T) { + for _, secondCallType := range []string{"init", "exec"} { + t.Run(fmt.Sprintf("second call %s", secondCallType), func(t *testing.T) { + for _, test := range []struct { + description string + msg string + isSuccess bool + isErrorEncrypted bool + expectedError string + }{ + { + description: "Send invalid input", + msg: `{\"blabla\":{}}`, + isSuccess: false, + isErrorEncrypted: true, + expectedError: "unknown variant", + }, + { + description: "Success", + msg: `{\"wasm_msg\":{\"ty\": \"success\"}}`, + isSuccess: true, + isErrorEncrypted: true, + expectedError: "", + }, + { + description: "StdError", + msg: `{\"wasm_msg\":{\"ty\": \"err\"}}`, + isSuccess: false, + isErrorEncrypted: true, + expectedError: "custom error", + }, + { + description: "Panic", + msg: `{\"wasm_msg\":{\"ty\": \"panic\"}}`, + isSuccess: false, + isErrorEncrypted: false, + expectedError: "panicked", + }, + } { + t.Run(test.description, func(t *testing.T) { + ctx, keeper, fromCodeID, _, walletA, privKeyA, _, _ := setupTest(t, from.WasmFilePath, sdk.NewCoins()) + + wasmCode, err := os.ReadFile(to.WasmFilePath) + require.NoError(t, err) + + toCodeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") + codeInfo, err := keeper.GetCodeInfo(ctx, toCodeID) + require.NoError(t, err) + toCodeHash := hex.EncodeToString(codeInfo.CodeHash) + require.NoError(t, err) + + toAddress := sdk.AccAddress{} + if secondCallType != "init" { + _, _, toAddress, _, err = initHelper(t, keeper, ctx, toCodeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, to.IsCosmWasmV1, defaultGasForTests) + require.Empty(t, err) + } + + fromAddress := sdk.AccAddress{} + if firstCallType == "init" { + _, _, _, _, err = initHelper(t, keeper, ctx, fromCodeID, walletA, walletA, privKeyA, fmt.Sprintf(`{"call_to_%s":{"code_id": %d, "addr": "%s", "code_hash": "%s", "label": "%s", "msg": "%s"}}`, secondCallType, toCodeID, toAddress, toCodeHash, "blabla", test.msg), test.isErrorEncrypted, true, defaultGasForTests) + } else if firstCallType == "exec" { + _, _, fromAddress, _, err = initHelper(t, keeper, ctx, fromCodeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, from.IsCosmWasmV1, defaultGasForTests) + require.Empty(t, err) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, err = migrateHelper(t, keeper, ctx, newCodeId, fromAddress, walletA, privKeyA, fmt.Sprintf(`{"call_to_%s":{"code_id": %d, "addr": "%s", "code_hash": "%s", "label": "%s", "msg": "%s"}}`, secondCallType, toCodeID, toAddress, toCodeHash, "blabla", test.msg), test.isErrorEncrypted, true, math.MaxUint64) + } + + if test.isSuccess { + require.Empty(t, err) + } else { + require.NotEmpty(t, err) + require.Contains(t, fmt.Sprintf("%+v", err), test.expectedError) + } + }) + } + }) + } + }) + } + }) + } + }) + } +} + +func TestCosmosMsgCustomDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, false, true, defaultGasForTests, -1, sdk.NewCoins()) + require.Empty(t, err) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"cosmos_msg_custom":{}}`, false, true, math.MaxUint64) + require.Contains(t, migrateErr.Error(), "Custom variant not supported: invalid CosmosMsg from the contract") +} + +func TestV1SendsFundsWithReplyDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + + _, _, _, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"deposit_to_contract":{}}`, false, true, defaultGasForTests, 200) + require.Empty(t, err) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"send_funds_with_reply":{}}`, true, true, math.MaxUint64) + + require.Empty(t, migErr) +} + +func TestV1SendsFundsWithErrorWithReplyDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"send_funds_with_error_with_reply":{}}`, false, true, math.MaxUint64) + + require.NotEmpty(t, err) + require.Contains(t, fmt.Sprintf("%+v", err), "an sdk error occoured while sending a sub-message") +} + +func TestCallbackSanityDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, initEvents, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + requireEvents(t, + initEvents, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "init", Value: "🌈"}, + }, + }, + ) + + newCodeId, newCodeHash := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + res, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"a":{"contract_addr":"%s","code_hash":"%s","x":2,"y":3}}`, contractAddress.String(), newCodeHash), true, true, defaultGasForTests) + require.Empty(t, migErr) + + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "banana", Value: "🍌"}, + }, + { + {Key: "kiwi", Value: "🥝"}, + {Key: "contract_address", Value: contractAddress.String()}, + }, + { + {Key: "watermelon", Value: "🍉"}, + {Key: "contract_address", Value: contractAddress.String()}, + }, + }, + res.WasmEvents, + ) + + require.Equal(t, []byte{2, 3}, res.Data) +} + +func TestCodeHashExecCallExecDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + newCodeId, newCodeHash := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, addr, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + t.Run("GoodCodeHash", func(t *testing.T) { + res, err := migrateHelper(t, keeper, ctx, newCodeId, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr, newCodeHash, `{\"c\":{\"x\":1,\"y\":1}}`), true, true, defaultGasForTests) + + require.Empty(t, err) + + var newContractBech32 string + for _, v := range res.WasmEvents[1] { + if v.Key == "contract_address" { + newContractBech32 = v.Value + break + } + } + require.NotEmpty(t, newContractBech32) + + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: addr.String()}, + {Key: "b", Value: "b"}, + }, + { + {Key: "contract_address", Value: newContractBech32}, + {Key: "watermelon", Value: "🍉"}, + }, + }, + res.WasmEvents, + ) + }) + t.Run("EmptyCodeHash", func(t *testing.T) { + _, err := migrateHelper(t, keeper, ctx, newCodeId, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"","msg":"%s"}}`, addr, `{\"c\":{\"x\":1,\"y\":1}}`), false, true, defaultGasForTests) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "failed to validate transaction", + ) + }) + t.Run("TooBigCodeHash", func(t *testing.T) { + _, err := migrateHelper(t, keeper, ctx, newCodeId, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%sa","msg":"%s"}}`, addr, newCodeHash, `{\"c\":{\"x\":1,\"y\":1}}`), true, true, defaultGasForTests) + + require.NotEmpty(t, err) + if true { + require.Contains(t, + err.Error(), + "v1_sanity_contract_v2::msg::ExecuteMsg: Expected to parse either a `true`, `false`, or a `null`.", + ) + } else { + require.Contains(t, + err.Error(), + "parsing test_contract::contract::HandleMsg: Expected to parse either a `true`, `false`, or a `null`.", + ) + } + }) + t.Run("TooSmallCodeHash", func(t *testing.T) { + _, err := migrateHelper(t, keeper, ctx, newCodeId, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr, newCodeHash[0:63], `{\"c\":{\"x\":1,\"y\":1}}`), false, true, defaultGasForTests) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "failed to validate transaction", + ) + }) + t.Run("IncorrectCodeHash", func(t *testing.T) { + _, err := migrateHelper(t, keeper, ctx, newCodeId, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","msg":"%s"}}`, addr, `{\"c\":{\"x\":1,\"y\":1}}`), false, true, defaultGasForTests) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "failed to validate transaction", + ) + }) +} + +func TestGasIsChargedForExecCallbackToExecDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, newCodeHash := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, addr, walletA, privKeyA, fmt.Sprintf(`{"a":{"contract_addr":"%s","code_hash":"%s","x":1,"y":2}}`, addr, newCodeHash), true, true, math.MaxUint64, 3) + require.Empty(t, migrateErr) +} + +func TestMsgSenderInCallbackDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + newCodeId, newCodeHash := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + res, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, addr, walletA, privKeyA, fmt.Sprintf(`{"callback_to_log_msg_sender":{"to":"%s","code_hash":"%s"}}`, addr.String(), newCodeHash), true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + requireEvents(t, []ContractEvent{ + { + {Key: "contract_address", Value: addr.String()}, + {Key: "hi", Value: "hey"}, + }, + { + {Key: "contract_address", Value: addr.String()}, + {Key: "msg.sender", Value: addr.String()}, + }, + }, res.WasmEvents) +} + +func TestContractSendFundsDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + _, _, _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"deposit_to_contract":{}}`, false, true, defaultGasForTests, 17) + + require.Empty(t, execErr) + + contractCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr) + walletCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletA) + + require.Equal(t, "17denom", contractCoinsBefore.String()) + require.Equal(t, "199983denom", walletCoinsBefore.String()) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, addr, walletA, privKeyA, fmt.Sprintf(`{"send_funds":{"from":"%s","to":"%s","denom":"%s","amount":%d}}`, addr.String(), walletA.String(), "denom", 17), true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + contractCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr) + walletCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletA) + + require.Equal(t, "", contractCoinsAfter.String()) + require.Equal(t, "200000denom", walletCoinsAfter.String()) +} + +func TestContractSendFundsToExecCallbackDuringMigrate(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + _, _, addr2, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + contractCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr) + contract2CoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr2) + walletCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletA) + + require.Equal(t, "", contractCoinsBefore.String()) + require.Equal(t, "", contract2CoinsBefore.String()) + require.Equal(t, "200000denom", walletCoinsBefore.String()) + + _, _, _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"deposit_to_contract":{}}`, false, true, defaultGasForTests, 17) + require.Empty(t, execErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, addr, walletA, privKeyA, fmt.Sprintf(`{"send_funds_to_exec_callback":{"to":"%s","denom":"%s","amount":%d,"code_hash":"%s"}}`, addr2.String(), "denom", 17, codeHash), true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + contractCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr) + contract2CoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr2) + walletCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletA) + + require.Equal(t, "", contractCoinsAfter.String()) + require.Equal(t, "17denom", contract2CoinsAfter.String()) + require.Equal(t, "199983denom", walletCoinsAfter.String()) +} + +func TestContractSendFundsToExecCallbackNotEnoughDuringMigrate(t *testing.T, +) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + _, _, addr2, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + contractCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr) + contract2CoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr2) + walletCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletA) + + require.Equal(t, "", contractCoinsBefore.String()) + require.Equal(t, "", contract2CoinsBefore.String()) + require.Equal(t, "200000denom", walletCoinsBefore.String()) + + _, _, _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"deposit_to_contract":{}}`, false, true, defaultGasForTests, 17) + require.Empty(t, execErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + + _, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, addr, walletA, privKeyA, fmt.Sprintf(`{"send_funds_to_exec_callback":{"to":"%s","denom":"%s","amount":%d,"code_hash":"%s"}}`, addr2.String(), "denom", 19, codeHash), false, true, defaultGasForTests) + + require.NotNil(t, migrateErr.CosmWasm.GenericErr) + require.Contains(t, migrateErr.CosmWasm.GenericErr.Msg, "insufficient funds") + + contractCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr) + contract2CoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr2) + walletCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletA) + + // The state here should have been reverted by the app but in go-tests we create our own keeper + // so it is not reverted in this case. + require.Equal(t, "17denom", contractCoinsAfter.String()) + require.Equal(t, "", contract2CoinsAfter.String()) + require.Equal(t, "199983denom", walletCoinsAfter.String()) +} + +func TestExecCallbackContractErrorDuring(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + require.Equal(t, 1, len(initEvents)) + + newCodeId, newCodeHash := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + + res, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"callback_contract_error":{"contract_addr":"%s","code_hash":"%s"}}`, contractAddress, newCodeHash), true, true, defaultGasForTests) // using the new code hash because migration is done by the time the callback is executed + + require.NotNil(t, migErr.CosmWasm.GenericErr) + require.Contains(t, migErr.CosmWasm.GenericErr.Msg, "la la 🤯") + require.Empty(t, res.Data) +} + +func TestExecCallbackBadParamDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + require.Equal(t, 1, len(initEvents)) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + + res, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"callback_contract_bad_param":{"contract_addr":"%s"}}`, contractAddress), true, true, defaultGasForTests) + + require.NotNil(t, err.CosmWasm.GenericErr) + require.Contains(t, err.CosmWasm.GenericErr.Msg, "v1_sanity_contract_v2::msg::ExecuteMsg") + require.Contains(t, err.CosmWasm.GenericErr.Msg, "unknown variant `callback_contract_bad_param`") + require.Empty(t, res.Data) +} + +func TestCallbackExecuteParamErrorDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, newCodeHash := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + + msg := fmt.Sprintf(`{"a":{"code_hash":"%s","contract_addr":"notanaddress","x":2,"y":3}}`, newCodeHash) + + _, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, msg, false, true, defaultGasForTests) + + require.Contains(t, err.Error(), "invalid address") +} + +func TestExecuteIllegalInputErrorDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + + _, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `bad input`, true, true, defaultGasForTests) + + require.NotNil(t, err.CosmWasm.GenericErr) + require.Contains(t, err.CosmWasm.GenericErr.Msg, "Error parsing") +} + +func TestExecContractErrorDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + + t.Run("generic_err", func(t *testing.T) { + _, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"generic_err"}}`, true, true, defaultGasForTests) + + require.NotNil(t, err.CosmWasm.GenericErr) + require.Contains(t, err.CosmWasm.GenericErr.Msg, "la la 🤯") + }) + t.Run("invalid_base64", func(t *testing.T) { + _, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"invalid_base64"}}`, true, true, defaultGasForTests) + + if true { + require.NotNil(t, err.CosmWasm.GenericErr) + require.Contains(t, err.CosmWasm.GenericErr.Msg, "ra ra 🤯") + } else { + require.NotNil(t, err.CosmWasm.InvalidBase64) + require.Equal(t, "ra ra 🤯", err.CosmWasm.InvalidBase64.Msg) + } + }) + t.Run("invalid_utf8", func(t *testing.T) { + _, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"invalid_utf8"}}`, true, true, defaultGasForTests) + + if true { + require.NotNil(t, err.CosmWasm.GenericErr) + require.Contains(t, err.CosmWasm.GenericErr.Msg, "ka ka 🤯") + } else { + require.NotNil(t, err.CosmWasm.InvalidUtf8) + require.Equal(t, "ka ka 🤯", err.CosmWasm.InvalidUtf8.Msg) + } + }) + t.Run("not_found", func(t *testing.T) { + _, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"not_found"}}`, true, true, defaultGasForTests) + + if true { + require.NotNil(t, err.CosmWasm.GenericErr) + require.Contains(t, err.CosmWasm.GenericErr.Msg, "za za 🤯") + } else { + require.NotNil(t, err.CosmWasm.NotFound) + require.Equal(t, "za za 🤯", err.CosmWasm.NotFound.Kind) + } + }) + t.Run("parse_err", func(t *testing.T) { + _, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"parse_err"}}`, true, true, defaultGasForTests) + + if true { + require.NotNil(t, err.CosmWasm.GenericErr) + require.Contains(t, err.CosmWasm.GenericErr.Msg, "na na 🤯") + require.Contains(t, err.CosmWasm.GenericErr.Msg, "pa pa 🤯") + } else { + require.NotNil(t, err.CosmWasm.ParseErr) + require.Equal(t, "na na 🤯", err.CosmWasm.ParseErr.Target) + require.Equal(t, "pa pa 🤯", err.CosmWasm.ParseErr.Msg) + } + }) + t.Run("serialize_err", func(t *testing.T) { + _, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"serialize_err"}}`, true, true, defaultGasForTests) + + if true { + require.NotNil(t, err.CosmWasm.GenericErr) + require.Contains(t, err.CosmWasm.GenericErr.Msg, "ba ba 🤯") + require.Contains(t, err.CosmWasm.GenericErr.Msg, "ga ga 🤯") + } else { + require.NotNil(t, err.CosmWasm.SerializeErr) + require.Equal(t, "ba ba 🤯", err.CosmWasm.SerializeErr.Source) + require.Equal(t, "ga ga 🤯", err.CosmWasm.SerializeErr.Msg) + } + }) + t.Run("unauthorized", func(t *testing.T) { + _, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"unauthorized"}}`, true, true, defaultGasForTests) + + if true { + // Not supported in V1 + require.NotNil(t, err.CosmWasm.GenericErr) + require.Contains(t, err.CosmWasm.GenericErr.Msg, "catch-all 🤯") + } else { + require.NotNil(t, err.CosmWasm.Unauthorized) + } + }) + t.Run("underflow", func(t *testing.T) { + _, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"underflow"}}`, true, true, defaultGasForTests) + + if true { + // Not supported in V1 + require.NotNil(t, err.CosmWasm.GenericErr) + require.Contains(t, err.CosmWasm.GenericErr.Msg, "catch-all 🤯") + } else { + require.NotNil(t, err.CosmWasm.Underflow) + require.Equal(t, "minuend 🤯", err.CosmWasm.Underflow.Minuend) + require.Equal(t, "subtrahend 🤯", err.CosmWasm.Underflow.Subtrahend) + } + }) +} + +func TestExecPanicDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + + _, err := migrateHelper(t, keeper, ctx, newCodeId, addr, walletA, privKeyA, `{"panic":{}}`, false, true, defaultGasForTests) + + require.NotNil(t, err.CosmWasm.GenericErr) + require.Contains(t, err.CosmWasm.GenericErr.Msg, "the contract panicked") +} + +func TestCanonicalizeAddressErrorsDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + require.Equal(t, 1, len(initEvents)) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + + // this function should handle errors internally and return gracefully + res, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"test_canonicalize_address_errors":{}}`, true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + require.Equal(t, "🤟", string(res.Data)) +} + +func TestV1ReplyChainAllSuccessDuringMigrate(t *testing.T) { + amountOfContracts := uint64(5) + ctx, keeper, codeIds, codeHashes, walletA, privKeyA, _, _ := setupChainTest(t, TestContractPaths[v1Contract], sdk.NewCoins(), amountOfContracts) + contractAddresses := make([]sdk.AccAddress, amountOfContracts) + + for i := uint64(0); i < amountOfContracts; i++ { + _, _, contractAddresses[i], _, _ = initHelper(t, keeper, ctx, codeIds[i], walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + } + + executeDetails := make([]ExecuteDetails, amountOfContracts-1) + for i := uint64(1); i < amountOfContracts; i++ { + executeDetails[i-1] = ExecuteDetails{ + ContractAddress: contractAddresses[i].String(), + ContractHash: codeHashes[i], // using the original code hash as only contractAddresses[0] is being migrated + ShouldError: false, + MsgId: 9000, + Data: fmt.Sprintf("%d", i), + } + } + + marshaledDetails, err := json.Marshal(executeDetails) + require.Empty(t, err) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + + res, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddresses[0], walletA, privKeyA, fmt.Sprintf(`{"execute_multiple_contracts":{"details":%s}}`, string(marshaledDetails)), true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + expectedFlow := "" + for i := uint64(amountOfContracts - 1); i > 0; i-- { + expectedFlow += contractAddresses[i].String() + " -> " + } + + expectedFlow += contractAddresses[0].String() + + require.Equal(t, expectedFlow, string(res.Data)) +} + +func TestV1ReplyChainPartiallyRepliedDuringMigrate(t *testing.T) { + amountOfContracts := uint64(10) + amountOfContractToBeReplied := uint64(5) + + ctx, keeper, codeIds, codeHashes, walletA, privKeyA, _, _ := setupChainTest(t, TestContractPaths[v1Contract], sdk.NewCoins(), amountOfContracts) + contractAddresses := make([]sdk.AccAddress, amountOfContracts) + + for i := uint64(0); i < amountOfContracts; i++ { + _, _, contractAddresses[i], _, _ = initHelper(t, keeper, ctx, codeIds[i], walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + } + + executeDetails := make([]ExecuteDetails, amountOfContracts-1) + for i := uint64(1); i < amountOfContracts; i++ { + msgId := uint64(9000) + if i >= amountOfContractToBeReplied { + msgId = 0 + } + + executeDetails[i-1] = ExecuteDetails{ + ContractAddress: contractAddresses[i].String(), + ContractHash: codeHashes[i], // using the original code hash as only contractAddresses[0] is being migrated + ShouldError: false, + MsgId: msgId, + Data: fmt.Sprintf("%d", i), + } + } + + marshaledDetails, err := json.Marshal(executeDetails) + require.Empty(t, err) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + res, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddresses[0], walletA, privKeyA, fmt.Sprintf(`{"execute_multiple_contracts":{"details": %s}}`, string(marshaledDetails)), true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + expectedFlow := "" + + expectedFlow += fmt.Sprintf("%d", amountOfContractToBeReplied) + " -> " + + for i := uint64(amountOfContractToBeReplied - 2); i > 0; i-- { + expectedFlow += contractAddresses[i].String() + " -> " + } + + expectedFlow += contractAddresses[0].String() + + require.Equal(t, expectedFlow, string(res.Data)) +} + +func TestV1ReplyChainWithErrorDuringMigrate(t *testing.T) { + amountOfContracts := uint64(5) + ctx, keeper, codeIds, codeHashes, walletA, privKeyA, _, _ := setupChainTest(t, TestContractPaths[v1Contract], sdk.NewCoins(), amountOfContracts) + contractAddresses := make([]sdk.AccAddress, amountOfContracts) + + for i := uint64(0); i < amountOfContracts; i++ { + _, _, contractAddresses[i], _, _ = initHelper(t, keeper, ctx, codeIds[i], walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + } + + executeDetails := make([]ExecuteDetails, amountOfContracts-1) + for i := uint64(1); i < amountOfContracts; i++ { + executeDetails[i-1] = ExecuteDetails{ + ContractAddress: contractAddresses[i].String(), + ContractHash: codeHashes[i], // using the original code hash as only contractAddresses[0] is being migrated + ShouldError: false, + MsgId: 9000, + Data: fmt.Sprintf("%d", i), + } + } + + executeDetails[amountOfContracts-2].ShouldError = true + + marshaledDetails, err := json.Marshal(executeDetails) + require.Empty(t, err) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + res, migrateErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddresses[0], walletA, privKeyA, fmt.Sprintf(`{"execute_multiple_contracts":{"details": %s}}`, string(marshaledDetails)), true, true, math.MaxUint64) + require.Empty(t, migrateErr) + + expectedFlow := "err -> " + for i := uint64(amountOfContracts - 4); i > 0; i-- { + expectedFlow += contractAddresses[i].String() + " -> " + } + + expectedFlow += contractAddresses[0].String() + + require.Equal(t, expectedFlow, string(res.Data)) +} + +func TestLastMsgMarkerDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop": {}}`, true, true, defaultGasForTests) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + + // reset value before test + keeper.LastMsgManager.SetMarker(false) + + _, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"last_msg_marker_nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, err) + + require.True(t, keeper.LastMsgManager.GetMarker()) +} diff --git a/x/compute/internal/keeper/secret_contracts_utils_test.go b/x/compute/internal/keeper/secret_contracts_utils_test.go index afc852f6f..45d3bb1df 100644 --- a/x/compute/internal/keeper/secret_contracts_utils_test.go +++ b/x/compute/internal/keeper/secret_contracts_utils_test.go @@ -357,17 +357,28 @@ func (wasmGasMeter *WasmCounterGasMeter) GetWasmCounter() uint64 { var _ sdk.GasMeter = (*WasmCounterGasMeter)(nil) // check interface func queryHelper( - t *testing.T, keeper Keeper, ctx sdk.Context, - contractAddr sdk.AccAddress, input string, - isErrorEncrypted bool, isV1Contract bool, gas uint64, + t *testing.T, + keeper Keeper, + ctx sdk.Context, + contractAddr sdk.AccAddress, + input string, + isErrorEncrypted bool, + isV1Contract bool, + gas uint64, ) (string, cosmwasm.StdError) { return queryHelperImpl(t, keeper, ctx, contractAddr, input, isErrorEncrypted, isV1Contract, gas, -1) } func queryHelperImpl( - t *testing.T, keeper Keeper, ctx sdk.Context, - contractAddr sdk.AccAddress, input string, - isErrorEncrypted bool, isV1Contract bool, gas uint64, wasmCallCount int64, + t *testing.T, + keeper Keeper, + ctx sdk.Context, + contractAddr sdk.AccAddress, + input string, + isErrorEncrypted bool, + isV1Contract bool, + gas uint64, + wasmCallCount int64, ) (string, cosmwasm.StdError) { hash, err := keeper.GetContractHash(ctx, contractAddr) require.NoError(t, err) @@ -425,9 +436,19 @@ func queryHelperImpl( //} func execHelperCustomWasmCount( - t *testing.T, keeper Keeper, ctx sdk.Context, - contractAddress sdk.AccAddress, txSender sdk.AccAddress, senderPrivKey crypto.PrivKey, execMsg string, - isErrorEncrypted bool, isV1Contract bool, gas uint64, coin int64, wasmCallCount int64, shouldSkipAttributes ...bool, + t *testing.T, + keeper Keeper, + ctx sdk.Context, + contractAddress sdk.AccAddress, + txSender sdk.AccAddress, + senderPrivKey crypto.PrivKey, + execMsg string, + isErrorEncrypted bool, + isV1Contract bool, + gas uint64, + coin int64, + wasmCallCount int64, + shouldSkipAttributes ...bool, ) ([]byte, sdk.Context, []byte, []ContractEvent, uint64, cosmwasm.StdError) { results, err := execTxBuilderImpl(t, keeper, ctx, contractAddress, txSender, senderPrivKey, []string{execMsg}, isErrorEncrypted, isV1Contract, gas, sdk.NewCoins(sdk.NewCoin("denom", sdk.NewInt(coin))), wasmCallCount, shouldSkipAttributes...) @@ -443,9 +464,19 @@ func execHelperCustomWasmCount( } func execHelperMultipleCoins( - t *testing.T, keeper Keeper, ctx sdk.Context, - contractAddress sdk.AccAddress, txSender sdk.AccAddress, senderPrivKey crypto.PrivKey, execMsg string, - isErrorEncrypted bool, isV1Contract bool, gas uint64, coins sdk.Coins, wasmCount int64, shouldSkipAttributes ...bool, + t *testing.T, + keeper Keeper, + ctx sdk.Context, + contractAddress sdk.AccAddress, + txSender sdk.AccAddress, + senderPrivKey crypto.PrivKey, + execMsg string, + isErrorEncrypted bool, + isV1Contract bool, + gas uint64, + coins sdk.Coins, + wasmCount int64, + shouldSkipAttributes ...bool, ) ([]byte, sdk.Context, []byte, []ContractEvent, uint64, cosmwasm.StdError) { results, err := execTxBuilderImpl(t, keeper, ctx, contractAddress, txSender, senderPrivKey, []string{execMsg}, isErrorEncrypted, isV1Contract, gas, coins, wasmCount, shouldSkipAttributes...) @@ -461,9 +492,18 @@ func execHelperMultipleCoins( } func execHelper( - t *testing.T, keeper Keeper, ctx sdk.Context, - contractAddress sdk.AccAddress, txSender sdk.AccAddress, senderPrivKey crypto.PrivKey, execMsg string, - isErrorEncrypted bool, isV1Contract bool, gas uint64, coin int64, shouldSkipAttributes ...bool, + t *testing.T, + keeper Keeper, + ctx sdk.Context, + contractAddress sdk.AccAddress, + txSender sdk.AccAddress, + senderPrivKey crypto.PrivKey, + execMsg string, + isErrorEncrypted bool, + isV1Contract bool, + gas uint64, + coin int64, + shouldSkipAttributes ...bool, ) ([]byte, sdk.Context, []byte, []ContractEvent, uint64, cosmwasm.StdError) { results, err := execTxBuilderImpl(t, keeper, ctx, contractAddress, txSender, senderPrivKey, []string{execMsg}, isErrorEncrypted, isV1Contract, gas, sdk.NewCoins(sdk.NewInt64Coin("denom", coin)), -1, shouldSkipAttributes...) @@ -478,17 +518,36 @@ func execHelper( } func execHelperMultipleMsgs( - t *testing.T, keeper Keeper, ctx sdk.Context, - contractAddress sdk.AccAddress, txSender sdk.AccAddress, senderPrivKey crypto.PrivKey, execMsg []string, - isErrorEncrypted bool, isV1Contract bool, gas uint64, coin int64, shouldSkipAttributes ...bool, + t *testing.T, + keeper Keeper, + ctx sdk.Context, + contractAddress sdk.AccAddress, + txSender sdk.AccAddress, + senderPrivKey crypto.PrivKey, + execMsg []string, + isErrorEncrypted bool, + isV1Contract bool, + gas uint64, + coin int64, + shouldSkipAttributes ...bool, ) ([]ExecResult, *ErrorResult) { return execTxBuilderImpl(t, keeper, ctx, contractAddress, txSender, senderPrivKey, execMsg, isErrorEncrypted, isV1Contract, gas, sdk.NewCoins(sdk.NewInt64Coin("denom", coin)), -1, shouldSkipAttributes...) } func execTxBuilderImpl( - t *testing.T, keeper Keeper, ctx sdk.Context, - contractAddress sdk.AccAddress, txSender sdk.AccAddress, senderPrivKey crypto.PrivKey, execMsgs []string, - isErrorEncrypted bool, isV1Contract bool, gas uint64, coins sdk.Coins, wasmCallCount int64, shouldSkipAttributes ...bool, + t *testing.T, + keeper Keeper, + ctx sdk.Context, + contractAddress sdk.AccAddress, + txSender sdk.AccAddress, + senderPrivKey crypto.PrivKey, + execMsgs []string, + isErrorEncrypted bool, + isV1Contract bool, + gas uint64, + coins sdk.Coins, + wasmCallCount int64, + shouldSkipAttributes ...bool, ) ([]ExecResult, *ErrorResult) { hash, err := keeper.GetContractHash(ctx, contractAddress) require.NoError(t, err) @@ -591,17 +650,37 @@ func execTxBuilderImpl( } func initHelper( - t *testing.T, keeper Keeper, ctx sdk.Context, - codeID uint64, creator, admin sdk.AccAddress, creatorPrivKey crypto.PrivKey, initMsg string, - isErrorEncrypted bool, isV1Contract bool, gas uint64, shouldSkipAttributes ...bool, + t *testing.T, + keeper Keeper, + ctx sdk.Context, + codeID uint64, + creator, + admin sdk.AccAddress, + creatorPrivKey crypto.PrivKey, + initMsg string, + isErrorEncrypted bool, + isV1Contract bool, + gas uint64, + shouldSkipAttributes ...bool, ) ([]byte, sdk.Context, sdk.AccAddress, []ContractEvent, cosmwasm.StdError) { return initHelperImpl(t, keeper, ctx, codeID, creator, admin, creatorPrivKey, initMsg, isErrorEncrypted, isV1Contract, gas, -1, sdk.NewCoins(), shouldSkipAttributes...) } func initHelperImpl( - t *testing.T, keeper Keeper, ctx sdk.Context, - codeID uint64, creator, admin sdk.AccAddress, creatorPrivKey crypto.PrivKey, initMsg string, - isErrorEncrypted bool, isV1Contract bool, gas uint64, wasmCallCount int64, sentFunds sdk.Coins, shouldSkipAttributes ...bool, + t *testing.T, + keeper Keeper, + ctx sdk.Context, + codeID uint64, + creator, + admin sdk.AccAddress, + creatorPrivKey crypto.PrivKey, + initMsg string, + isErrorEncrypted bool, + isV1Contract bool, + gas uint64, + wasmCallCount int64, + sentFunds sdk.Coins, + shouldSkipAttributes ...bool, ) ([]byte, sdk.Context, sdk.AccAddress, []ContractEvent, cosmwasm.StdError) { codeInfo, err := keeper.GetCodeInfo(ctx, codeID) require.NoError(t, err) @@ -698,10 +777,18 @@ type v1QueryResponse struct { } func migrateHelper( - t *testing.T, keeper Keeper, ctx sdk.Context, + t *testing.T, + keeper Keeper, + ctx sdk.Context, newCodeId uint64, - contractAddress sdk.AccAddress, txSender sdk.AccAddress, senderPrivKey crypto.PrivKey, migrateMsg string, - isErrorEncrypted bool, isV1Contract bool, gas uint64, shouldSkipAttributes ...bool, + contractAddress sdk.AccAddress, + txSender sdk.AccAddress, + senderPrivKey crypto.PrivKey, + migrateMsg string, + isErrorEncrypted bool, + isV1Contract bool, + gas uint64, + wasmCallCount ...int64, ) (MigrateResult, *ErrorResult) { codeInfo, err := keeper.GetCodeInfo(ctx, newCodeId) require.NoError(t, err) @@ -747,6 +834,13 @@ func migrateHelper( gasAfter := ctx.GasMeter().GasConsumed() gasUsed := gasAfter - gasBefore + if len(wasmCallCount) == 0 { + // default, just check that at least 1 call happened + require.NotZero(t, gasMeter.GetWasmCounter(), err) + } else { + require.Equal(t, uint64(wasmCallCount[0]), gasMeter.GetWasmCounter(), err) + } + if err != nil { result := MigrateResult{ Nonce: nil, @@ -766,7 +860,7 @@ func migrateHelper( } // wasmEvents come from all the callbacks as well - wasmEvents := tryDecryptWasmEvents(ctx, nonce, shouldSkipAttributes...) + wasmEvents := tryDecryptWasmEvents(ctx, nonce) // Data is the output of only the first call data := getDecryptedData(t, execResult, nonce) From ff1576619f9330fc8c7dad92fd5debdc1e3b2fa0 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Sun, 2 Jul 2023 20:59:54 +0300 Subject: [PATCH 057/164] Update codeID in contractInfo on migrate Also set CurrentContractKey = ogContractKey on init (not necessary ATM but can prevent bugs in the enclave in the future) --- x/compute/internal/keeper/keeper.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index 2a0daecaa..fa3fcd2c8 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -526,7 +526,7 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.A k.setContractInfo(ctx, contractAddress, &contractInfo) k.SetContractKey(ctx, contractAddress, &types.ContractKey{ OgContractKey: ogContractKey, - CurrentContractKey: nil, + CurrentContractKey: ogContractKey, CurrentContractKeyProof: nil, }) store.Set(types.GetContractLabelPrefix(label), contractAddress) @@ -576,7 +576,7 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.A k.setContractInfo(ctx, contractAddress, &contractInfo) k.SetContractKey(ctx, contractAddress, &types.ContractKey{ OgContractKey: ogContractKey, - CurrentContractKey: nil, + CurrentContractKey: ogContractKey, CurrentContractKeyProof: nil, }) store.Set(types.GetContractLabelPrefix(label), contractAddress) @@ -1328,8 +1328,8 @@ func (k Keeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller env := types.NewEnv(ctx, caller, sdk.Coins{}, contractAddress, contractKey, random) - adminProof := k.GetContractInfo(ctx, contractAddress).AdminProof - admin := k.GetContractInfo(ctx, contractAddress).Admin + adminProof := contractInfo.AdminProof + admin := contractInfo.Admin adminAddr, err := sdk.AccAddressFromBech32(admin) if err != nil { @@ -1376,6 +1376,8 @@ func (k Keeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller historyEntry := contractInfo.AddMigration(ctx, newCodeID, msg) k.appendToContractHistory(ctx, contractAddress, historyEntry) k.addToContractCodeSecondaryIndex(ctx, contractAddress, historyEntry) + + contractInfo.CodeID = newCodeID k.setContractInfo(ctx, contractAddress, &contractInfo) ctx.EventManager().EmitEvent(sdk.NewEvent( From 105a9d9d6bf34af8f0258d61d8b1993f7cb20522 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Sun, 2 Jul 2023 23:12:56 +0300 Subject: [PATCH 058/164] Fix AminoSdkMsg deserialization of Msg{Update,Clear}Admin --- cosmwasm/enclaves/shared/cosmos-types/src/types.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs index acd901d0e..581b333d1 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs @@ -337,11 +337,13 @@ pub enum AminoSdkMsg { code_id: String, msg: String, }, + #[serde(alias = "wasm/MsgUpdateAdmin")] MsgUpdateAdmin { sender: HumanAddr, new_admin: HumanAddr, contract: HumanAddr, }, + #[serde(alias = "wasm/MsgClearAdmin")] MsgClearAdmin { sender: HumanAddr, contract: HumanAddr, From 47c1a8c33a65a8f8063a202a38f4c128a73f7c43 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Sun, 2 Jul 2023 23:56:22 +0300 Subject: [PATCH 059/164] Fix verify_and_get_sdk_msg() of Msg{Update,Clear}Admin --- .../src/input_validation/msg_validation.rs | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs index dc25a13da..ab9589522 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs @@ -56,29 +56,21 @@ pub fn verify_and_get_sdk_msg<'sd>( contract, .. } => { - let empty_canon = &CanonicalAddr(Binary(vec![])); - let sent_admin = sent_admin.unwrap_or(empty_canon); - sent_sender == sender - && sent_admin == sender + && sent_admin.is_some() + && sent_admin.unwrap() == sender && sent_contract_address == contract && &sent_wasm_input.to_vec() == msg } DirectSdkMsg::MsgUpdateAdmin { - sender, - new_admin, - contract, - } => { - let empty_canon = &CanonicalAddr(Binary(vec![])); - let empty_human = HumanAddr("".to_string()); - let sent_admin = &HumanAddr::from_canonical(sent_admin.unwrap_or(empty_canon)) - .unwrap_or(empty_human); - - sent_sender == sender && sent_admin == new_admin && sent_contract_address == contract + sender, contract, .. } - DirectSdkMsg::MsgClearAdmin { sender, contract } => { + | DirectSdkMsg::MsgClearAdmin { + sender, contract, .. + } => { sent_sender == sender - && sent_admin == Some(&CanonicalAddr(Binary(vec![]))) + && sent_admin.is_some() + && sent_admin.unwrap() == sender && sent_contract_address == contract } DirectSdkMsg::MsgRecvPacket { packet, .. } => match verify_params_types { From d8dc1e6bd9be62629c890cac61045f73a4b90171 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Sun, 2 Jul 2023 23:57:04 +0300 Subject: [PATCH 060/164] Fix TestCheckGas --- x/compute/internal/keeper/secret_contracts_exec_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/compute/internal/keeper/secret_contracts_exec_test.go b/x/compute/internal/keeper/secret_contracts_exec_test.go index 22cdb908c..f9e3d6081 100644 --- a/x/compute/internal/keeper/secret_contracts_exec_test.go +++ b/x/compute/internal/keeper/secret_contracts_exec_test.go @@ -2293,8 +2293,8 @@ func TestCheckGas(t *testing.T) { _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"Nop":{}}`, true, true, defaultGasForTests) require.Empty(t, initErr) - // 1031 is the sum of all the overhead that goes into a contract call beyond the base cost (reading/writing keys, calculations, etc) - baseContractUsage := types.InstanceCost + 1031 + // 1097 is the sum of all the overhead that goes into a contract call beyond the base cost (reading/writing keys, calculations, etc) + baseContractUsage := types.InstanceCost + 1097 _, _, _, events, baseGasUsed, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"check_gas":{}}`, true, true, defaultGasForTests, 0) require.Empty(t, err) From f00a8135fa1e827199e73c3277d36c9b41d3fa22 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Mon, 3 Jul 2023 07:34:19 +0300 Subject: [PATCH 061/164] Fix TestConsumeExact --- x/compute/internal/keeper/secret_contracts_exec_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/compute/internal/keeper/secret_contracts_exec_test.go b/x/compute/internal/keeper/secret_contracts_exec_test.go index f9e3d6081..dde26ceb2 100644 --- a/x/compute/internal/keeper/secret_contracts_exec_test.go +++ b/x/compute/internal/keeper/secret_contracts_exec_test.go @@ -2313,7 +2313,7 @@ func TestConsumeExact(t *testing.T) { require.Empty(t, initErr) // not sure where the 16 extra gas comes vs the previous check_gas test, but it makes everything play nice, so.... - baseContractUsage := types.InstanceCost + 1031 - 16 + baseContractUsage := types.InstanceCost + 1097 - 16 for _, test := range []struct { description string From ef51d8a68db6545fe8bf9d35bb01a99b4df2addd Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Mon, 3 Jul 2023 14:41:43 +0300 Subject: [PATCH 062/164] Copy all query tests and modify to test during and after migrate --- .../test-compute-contract-v2/src/contract.rs | 4 +- .../keeper/secret_contracts_migrate_test.go | 856 +++++++++++++++++- .../keeper/testdata/v1-contract-v2.wasm | Bin 1939477 -> 1939477 bytes 3 files changed, 857 insertions(+), 3 deletions(-) diff --git a/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/contract.rs b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/contract.rs index 17b6a2ccf..05d720984 100644 --- a/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/contract.rs +++ b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/contract.rs @@ -1827,7 +1827,7 @@ pub fn init_new_contract(env: Env, _deps: DepsMut) -> StdResult { ), funds: vec![], label: "new202213".to_string(), - code_id: 1, + code_id: 2, }), gas_limit: Some(10000000_u64), reply_on: ReplyOn::Always, @@ -1849,7 +1849,7 @@ pub fn init_new_contract_with_error(env: Env, _deps: DepsMut) -> StdResult|GZ@lxtfg_)sl6Uj#vjc4BC{+Le delta 129 zcmWN=O%6j)6oAoO rMb4i!mnSkU&d@SsM8}wSCVcS8lo@jtELpK;! Date: Tue, 4 Jul 2023 21:17:21 +0300 Subject: [PATCH 063/164] Copy all submsg tests and modify to test during and after migrate --- .../test-compute-contract-v2/src/contract.rs | 4 +- cosmwasm/enclaves/test/Cargo.lock | 71 +- go-cosmwasm/Cargo.lock | 54 +- .../keeper/secret_contracts_migrate_test.go | 1404 +++++++++++++++++ .../keeper/testdata/v1-contract-v2.wasm | Bin 1939477 -> 1939477 bytes 5 files changed, 1476 insertions(+), 57 deletions(-) diff --git a/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/contract.rs b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/contract.rs index 05d720984..6859d073e 100644 --- a/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/contract.rs +++ b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/contract.rs @@ -1479,7 +1479,7 @@ pub fn send_multiple_sub_messages(env: Env, _deps: DepsMut) -> StdResult StdResult ), funds: vec![], label: "new202213".to_string(), - code_id: 1, + code_id: 2, }), gas_limit: Some(10000000_u64), reply_on: ReplyOn::Never, diff --git a/cosmwasm/enclaves/test/Cargo.lock b/cosmwasm/enclaves/test/Cargo.lock index d7d203361..6663daca8 100644 --- a/cosmwasm/enclaves/test/Cargo.lock +++ b/cosmwasm/enclaves/test/Cargo.lock @@ -17,7 +17,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.15", "libc", "winapi", ] @@ -42,9 +42,9 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "block-buffer" -version = "0.9.0" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] @@ -116,10 +116,23 @@ dependencies = [ ] [[package]] -name = "cpuid-bool" -version = "0.1.2" +name = "cpufeatures" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" +checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] [[package]] name = "derive_more" @@ -134,11 +147,12 @@ dependencies = [ [[package]] name = "digest" -version = "0.9.0" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "generic-array", + "block-buffer", + "crypto-common", ] [[package]] @@ -193,6 +207,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" + [[package]] name = "hex" version = "0.4.2" @@ -237,12 +257,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.11" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" -dependencies = [ - "cfg-if 0.1.10", -] +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] name = "memmap" @@ -256,20 +273,14 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.14.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.2", "libc", ] -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - [[package]] name = "parity-wasm" version = "0.41.0" @@ -503,15 +514,13 @@ dependencies = [ [[package]] name = "sha2" -version = "0.9.1" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2933378ddfeda7ea26f48c555bdad8bb446bf8a3d17832dc83e380d444cfb8c1" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" dependencies = [ - "block-buffer", - "cfg-if 0.1.10", - "cpuid-bool", + "cfg-if 1.0.0", + "cpufeatures", "digest", - "opaque-debug", ] [[package]] @@ -623,9 +632,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.12.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "unicode-ident" diff --git a/go-cosmwasm/Cargo.lock b/go-cosmwasm/Cargo.lock index 2650f0cb0..3b9b7b8bc 100644 --- a/go-cosmwasm/Cargo.lock +++ b/go-cosmwasm/Cargo.lock @@ -32,7 +32,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.15", "libc", "winapi", ] @@ -71,9 +71,9 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "block-buffer" -version = "0.9.0" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] @@ -171,6 +171,16 @@ dependencies = [ "libc", ] +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + [[package]] name = "ctor" version = "0.1.15" @@ -194,11 +204,12 @@ dependencies = [ [[package]] name = "digest" -version = "0.9.0" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "generic-array", + "block-buffer", + "crypto-common", ] [[package]] @@ -306,6 +317,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" + [[package]] name = "hex" version = "0.4.3" @@ -350,12 +367,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.17" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if 1.0.0", -] +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] name = "memmap" @@ -378,11 +392,11 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.14.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.2", "libc", ] @@ -392,12 +406,6 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5" -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - [[package]] name = "parity-wasm" version = "0.41.0" @@ -641,15 +649,13 @@ dependencies = [ [[package]] name = "sha2" -version = "0.9.9" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" dependencies = [ - "block-buffer", "cfg-if 1.0.0", "cpufeatures", "digest", - "opaque-debug", ] [[package]] diff --git a/x/compute/internal/keeper/secret_contracts_migrate_test.go b/x/compute/internal/keeper/secret_contracts_migrate_test.go index 8b9272fa5..a9f16c223 100644 --- a/x/compute/internal/keeper/secret_contracts_migrate_test.go +++ b/x/compute/internal/keeper/secret_contracts_migrate_test.go @@ -14,6 +14,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" v010types "github.com/scrtlabs/SecretNetwork/go-cosmwasm/types/v010" + "golang.org/x/exp/slices" cosmwasm "github.com/scrtlabs/SecretNetwork/go-cosmwasm/types" @@ -4977,3 +4978,1406 @@ func TestV1QueryV010ContractDuringMigrate(t *testing.T) { require.Empty(t, migErr) require.Equal(t, uint32(190), binary.BigEndian.Uint32(res.Data)) } + +func TestV1ReplyOnMultipleSubmessagesAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migErr) + + _, _, data, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"multiple_sub_messages":{}}`, true, true, math.MaxUint64, 0) + + require.Empty(t, err) + require.Equal(t, uint32(102), binary.BigEndian.Uint32(data)) +} + +func TestV1ReplyOnMultipleSubmessagesDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + res, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"multiple_sub_messages":{}}`, true, true, math.MaxUint64) + require.Empty(t, migErr) + + require.Equal(t, uint32(102), binary.BigEndian.Uint32(res.Data)) +} + +func TestV1MultipleSubmessagesNoReplyAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migErr) + + _, _, data, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"multiple_sub_messages_no_reply":{}}`, true, true, math.MaxUint64, 0) + + require.Empty(t, err) + require.Equal(t, uint32(10), binary.BigEndian.Uint32(data)) + + queryRes, qErr := queryHelper(t, keeper, ctx, contractAddress, `{"get":{}}`, true, true, math.MaxUint64) + require.Empty(t, qErr) + + var resp v1QueryResponse + e := json.Unmarshal([]byte(queryRes), &resp) + require.NoError(t, e) + require.Equal(t, uint32(16), resp.Get.Count) +} + +func TestV1MultipleSubmessagesNoReplyDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + res, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"multiple_sub_messages_no_reply":{}}`, true, true, math.MaxUint64) + require.Empty(t, migErr) + + require.Empty(t, migErr) + require.Equal(t, uint32(10), binary.BigEndian.Uint32(res.Data)) + + queryRes, qErr := queryHelper(t, keeper, ctx, contractAddress, `{"get":{}}`, true, true, math.MaxUint64) + require.Empty(t, qErr) + + var resp v1QueryResponse + e := json.Unmarshal([]byte(queryRes), &resp) + require.NoError(t, e) + require.Equal(t, uint32(16), resp.Get.Count) +} + +func TestSendEncryptedAttributesFromExecuteWithoutSubmessageWithoutReplyAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migErr) + + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_attributes":{}}`, true, true, defaultGasForTests, 0) + require.Empty(t, err) + + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🦄"}, + {Key: "attr2", Value: "🌈"}, + }, + }, + events, + ) +} + +func TestSendEncryptedAttributesFromExecuteWithoutSubmessageWithoutReplyDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + res, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"add_attributes":{}}`, true, true, math.MaxUint64) + require.Empty(t, migErr) + + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🦄"}, + {Key: "attr2", Value: "🌈"}, + }, + }, + res.WasmEvents, + ) +} + +func TestSendEncryptedAttributesFromExecuteWithSubmessageWithoutReplyAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migErr) + + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_attributes_with_submessage":{"id":0}}`, true, true, defaultGasForTests, 0) + require.Empty(t, err) + + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🦄"}, + {Key: "attr2", Value: "🌈"}, + }, + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr3", Value: "🍉"}, + {Key: "attr4", Value: "🥝"}, + }, + }, + events, + ) +} + +func TestSendEncryptedAttributesFromExecuteWithSubmessageWithoutReplyDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + res, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"add_attributes_with_submessage":{"id":0}}`, true, true, math.MaxUint64) + require.Empty(t, migErr) + + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🦄"}, + {Key: "attr2", Value: "🌈"}, + }, + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr3", Value: "🍉"}, + {Key: "attr4", Value: "🥝"}, + }, + }, + res.WasmEvents, + ) +} + +func TestV1SendsEncryptedAttributesFromExecuteWithSubmessageWithReplyAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migErr) + + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_attributes_with_submessage":{"id":2200}}`, true, true, defaultGasForTests, 0) + require.Empty(t, err) + + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🦄"}, + {Key: "attr2", Value: "🌈"}, + }, + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr3", Value: "🍉"}, + {Key: "attr4", Value: "🥝"}, + }, + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr5", Value: "🤯"}, + {Key: "attr6", Value: "🦄"}, + }, + }, + events, + ) +} + +func TestV1SendsEncryptedAttributesFromExecuteWithSubmessageWithReplyDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + res, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"add_attributes_with_submessage":{"id":2200}}`, true, true, math.MaxUint64) + require.Empty(t, migErr) + + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🦄"}, + {Key: "attr2", Value: "🌈"}, + }, + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr3", Value: "🍉"}, + {Key: "attr4", Value: "🥝"}, + }, + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr5", Value: "🤯"}, + {Key: "attr6", Value: "🦄"}, + }, + }, + res.WasmEvents, + ) +} + +func TestSendPlaintextAttributesFromExecuteWithoutSubmessageWithoutReplyAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migErr) + + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_plaintext_attributes":{}}`, true, true, defaultGasForTests, 0, true) + require.Empty(t, err) + + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🦄"}, + {Key: "attr2", Value: "🌈"}, + }, + }, + events, + ) +} + +func TestSendPlaintextAttributesFromExecuteWithoutSubmessageWithoutReplyDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + res, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"add_plaintext_attributes":{}}`, true, true, math.MaxUint64) + require.Empty(t, migErr) + + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🦄"}, + {Key: "attr2", Value: "🌈"}, + }, + }, + res.WasmEvents, + ) +} + +func TestSendPlaintextAttributesFromExecuteWithSubmessageWithoutReplyAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migErr) + + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_plaintext_attributes_with_submessage":{"id":0}}`, true, true, defaultGasForTests, 0, true) + require.Empty(t, err) + + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🦄"}, + {Key: "attr2", Value: "🌈"}, + }, + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr3", Value: "🍉"}, + {Key: "attr4", Value: "🥝"}, + }, + }, + events, + ) +} + +func TestSendPlaintextAttributesFromExecuteWithSubmessageWithoutReplyDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + res, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"add_plaintext_attributes_with_submessage":{"id":0}}`, true, true, math.MaxUint64) + require.Empty(t, migErr) + + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🦄"}, + {Key: "attr2", Value: "🌈"}, + }, + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr3", Value: "🍉"}, + {Key: "attr4", Value: "🥝"}, + }, + }, + res.WasmEvents, + ) +} + +func TestV1SendsPlaintextAttributesFromExecuteWithSubmessageWithReplyAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migErr) + + _, _, _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_plaintext_attributes_with_submessage":{"id":2300}}`, true, true, defaultGasForTests, 0, true) + require.Empty(t, err) + + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🦄"}, + {Key: "attr2", Value: "🌈"}, + }, + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr3", Value: "🍉"}, + {Key: "attr4", Value: "🥝"}, + }, + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr5", Value: "🤯"}, + {Key: "attr6", Value: "🦄"}, + }, + }, + events, + ) +} + +func TestV1SendsPlaintextAttributesFromExecuteWithSubmessageWithReplyDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + res, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"add_plaintext_attributes_with_submessage":{"id":2300}}`, true, true, math.MaxUint64) + require.Empty(t, migErr) + + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🦄"}, + {Key: "attr2", Value: "🌈"}, + }, + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr3", Value: "🍉"}, + {Key: "attr4", Value: "🥝"}, + }, + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr5", Value: "🤯"}, + {Key: "attr6", Value: "🦄"}, + }, + }, + res.WasmEvents, + ) +} + +func TestV1SendsEncryptedEventsFromExecuteWithoutSubmessageWithoutReplyAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migErr) + + nonce, ctx, _, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_events":{}}`, true, true, defaultGasForTests, 0) + require.Empty(t, err) + + events := ctx.EventManager().Events() + + hadCyber1 := false + hadCyber2 := false + + for _, e := range events { + if e.Type == "wasm-cyber1" { + require.False(t, hadCyber1) + attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🦄"}, + {Key: "attr2", Value: "🌈"}, + }, + attrs, + ) + + hadCyber1 = true + } + + if e.Type == "wasm-cyber2" { + require.False(t, hadCyber2) + attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr3", Value: "🐙"}, + {Key: "attr4", Value: "🦄"}, + }, + attrs, + ) + + hadCyber2 = true + } + } + + require.True(t, hadCyber1) + require.True(t, hadCyber2) +} + +func TestV1SendsEncryptedEventsFromExecuteWithoutSubmessageWithoutReplyDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + res, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"add_events":{}}`, true, true, math.MaxUint64) + require.Empty(t, migErr) + + events := res.Ctx.EventManager().Events() + + hadCyber1 := false + hadCyber2 := false + + for _, e := range events { + if e.Type == "wasm-cyber1" { + require.False(t, hadCyber1) + attrs, err := parseAndDecryptAttributes(e.Attributes, res.Nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🦄"}, + {Key: "attr2", Value: "🌈"}, + }, + attrs, + ) + + hadCyber1 = true + } + + if e.Type == "wasm-cyber2" { + require.False(t, hadCyber2) + attrs, err := parseAndDecryptAttributes(e.Attributes, res.Nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr3", Value: "🐙"}, + {Key: "attr4", Value: "🦄"}, + }, + attrs, + ) + + hadCyber2 = true + } + } + + require.True(t, hadCyber1) + require.True(t, hadCyber2) +} + +func TestV1SendsEncryptedEventsFromExecuteWithSubmessageWithoutReplyAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migErr) + + nonce, ctx, _, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_events_with_submessage":{"id":0}}`, true, true, defaultGasForTests, 0) + require.Empty(t, err) + + events := ctx.EventManager().Events() + + hadCyber1 := false + hadCyber2 := false + hadCyber3 := false + hadCyber4 := false + + for _, e := range events { + if e.Type == "wasm-cyber1" { + require.False(t, hadCyber1) + attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🦄"}, + {Key: "attr2", Value: "🌈"}, + }, + attrs, + ) + + hadCyber1 = true + } + + if e.Type == "wasm-cyber2" { + require.False(t, hadCyber2) + attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr3", Value: "🐙"}, + {Key: "attr4", Value: "🦄"}, + }, + attrs, + ) + + hadCyber2 = true + } + + if e.Type == "wasm-cyber3" { + require.False(t, hadCyber3) + attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🤯"}, + {Key: "attr2", Value: "🤟"}, + }, + attrs, + ) + + hadCyber3 = true + } + + if e.Type == "wasm-cyber4" { + require.False(t, hadCyber4) + attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr3", Value: "😅"}, + {Key: "attr4", Value: "🦄"}, + }, + attrs, + ) + + hadCyber4 = true + } + } + + require.True(t, hadCyber1) + require.True(t, hadCyber2) + require.True(t, hadCyber3) + require.True(t, hadCyber4) +} + +func TestV1SendsEncryptedEventsFromExecuteWithSubmessageWithoutReplyuringDMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + res, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"add_events_with_submessage":{"id":0}}`, true, true, math.MaxUint64) + require.Empty(t, migErr) + + events := res.Ctx.EventManager().Events() + + hadCyber1 := false + hadCyber2 := false + hadCyber3 := false + hadCyber4 := false + + for _, e := range events { + if e.Type == "wasm-cyber1" { + require.False(t, hadCyber1) + attrs, err := parseAndDecryptAttributes(e.Attributes, res.Nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🦄"}, + {Key: "attr2", Value: "🌈"}, + }, + attrs, + ) + + hadCyber1 = true + } + + if e.Type == "wasm-cyber2" { + require.False(t, hadCyber2) + attrs, err := parseAndDecryptAttributes(e.Attributes, res.Nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr3", Value: "🐙"}, + {Key: "attr4", Value: "🦄"}, + }, + attrs, + ) + + hadCyber2 = true + } + + if e.Type == "wasm-cyber3" { + require.False(t, hadCyber3) + attrs, err := parseAndDecryptAttributes(e.Attributes, res.Nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🤯"}, + {Key: "attr2", Value: "🤟"}, + }, + attrs, + ) + + hadCyber3 = true + } + + if e.Type == "wasm-cyber4" { + require.False(t, hadCyber4) + attrs, err := parseAndDecryptAttributes(e.Attributes, res.Nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr3", Value: "😅"}, + {Key: "attr4", Value: "🦄"}, + }, + attrs, + ) + + hadCyber4 = true + } + } + + require.True(t, hadCyber1) + require.True(t, hadCyber2) + require.True(t, hadCyber3) + require.True(t, hadCyber4) +} + +func TestV1SendsEncryptedEventsFromExecuteWithSubmessageWithReplyAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migErr) + nonce, ctx, _, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_events_with_submessage":{"id":2400}}`, true, true, defaultGasForTests, 0) + require.Empty(t, err) + + events := ctx.EventManager().Events() + + hadCyber1 := false + hadCyber2 := false + hadCyber3 := false + hadCyber4 := false + hadCyber5 := false + hadCyber6 := false + + for _, e := range events { + if e.Type == "wasm-cyber1" { + require.False(t, hadCyber1) + attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🦄"}, + {Key: "attr2", Value: "🌈"}, + }, + attrs, + ) + + hadCyber1 = true + } + + if e.Type == "wasm-cyber2" { + require.False(t, hadCyber2) + attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr3", Value: "🐙"}, + {Key: "attr4", Value: "🦄"}, + }, + attrs, + ) + + hadCyber2 = true + } + + if e.Type == "wasm-cyber3" { + require.False(t, hadCyber3) + attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🤯"}, + {Key: "attr2", Value: "🤟"}, + }, + attrs, + ) + + hadCyber3 = true + } + + if e.Type == "wasm-cyber4" { + require.False(t, hadCyber4) + attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr3", Value: "😅"}, + {Key: "attr4", Value: "🦄"}, + }, + attrs, + ) + + hadCyber4 = true + } + + if e.Type == "wasm-cyber5" { + require.False(t, hadCyber5) + attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "😗"}, + {Key: "attr2", Value: "😋"}, + }, + attrs, + ) + + hadCyber5 = true + } + + if e.Type == "wasm-cyber6" { + require.False(t, hadCyber6) + attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr3", Value: "😉"}, + {Key: "attr4", Value: "😊"}, + }, + attrs, + ) + + hadCyber6 = true + } + } + + require.True(t, hadCyber1) + require.True(t, hadCyber2) + require.True(t, hadCyber3) + require.True(t, hadCyber4) + require.True(t, hadCyber5) + require.True(t, hadCyber6) +} + +func TestV1SendsEncryptedEventsFromExecuteWithSubmessageWithReplyDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + res, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"add_events_with_submessage":{"id":2400}}`, true, true, math.MaxUint64) + require.Empty(t, migErr) + + events := res.Ctx.EventManager().Events() + + hadCyber1 := false + hadCyber2 := false + hadCyber3 := false + hadCyber4 := false + hadCyber5 := false + hadCyber6 := false + + for _, e := range events { + if e.Type == "wasm-cyber1" { + require.False(t, hadCyber1) + attrs, err := parseAndDecryptAttributes(e.Attributes, res.Nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🦄"}, + {Key: "attr2", Value: "🌈"}, + }, + attrs, + ) + + hadCyber1 = true + } + + if e.Type == "wasm-cyber2" { + require.False(t, hadCyber2) + attrs, err := parseAndDecryptAttributes(e.Attributes, res.Nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr3", Value: "🐙"}, + {Key: "attr4", Value: "🦄"}, + }, + attrs, + ) + + hadCyber2 = true + } + + if e.Type == "wasm-cyber3" { + require.False(t, hadCyber3) + attrs, err := parseAndDecryptAttributes(e.Attributes, res.Nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🤯"}, + {Key: "attr2", Value: "🤟"}, + }, + attrs, + ) + + hadCyber3 = true + } + + if e.Type == "wasm-cyber4" { + require.False(t, hadCyber4) + attrs, err := parseAndDecryptAttributes(e.Attributes, res.Nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr3", Value: "😅"}, + {Key: "attr4", Value: "🦄"}, + }, + attrs, + ) + + hadCyber4 = true + } + + if e.Type == "wasm-cyber5" { + require.False(t, hadCyber5) + attrs, err := parseAndDecryptAttributes(e.Attributes, res.Nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "😗"}, + {Key: "attr2", Value: "😋"}, + }, + attrs, + ) + + hadCyber5 = true + } + + if e.Type == "wasm-cyber6" { + require.False(t, hadCyber6) + attrs, err := parseAndDecryptAttributes(e.Attributes, res.Nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr3", Value: "😉"}, + {Key: "attr4", Value: "😊"}, + }, + attrs, + ) + + hadCyber6 = true + } + } + + require.True(t, hadCyber1) + require.True(t, hadCyber2) + require.True(t, hadCyber3) + require.True(t, hadCyber4) + require.True(t, hadCyber5) + require.True(t, hadCyber6) +} + +func TestV1SendsMixedAttributesAndEventsFromExecuteWithoutSubmessageWithoutReplyAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migErr) + nonce, ctx, _, logs, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_mixed_attributes_and_events":{}}`, true, true, defaultGasForTests, 0, true) + require.Empty(t, err) + + events := ctx.EventManager().Events() + + hadCyber1 := false + + for _, e := range events { + if e.Type == "wasm-cyber1" { + require.False(t, hadCyber1) + attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, false) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🦄"}, + {Key: "attr2", Value: "🌈"}, + }, + attrs, + ) + + hadCyber1 = true + } + } + + require.True(t, hadCyber1) + + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr3", Value: "🐙"}, + {Key: "attr4", Value: "🦄"}, + }, + }, + logs, + ) +} + +func TestV1SendsMixedAttributesAndEventsFromExecuteWithoutSubmessageWithoutReplyDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + res, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"add_mixed_attributes_and_events":{}}`, true, true, math.MaxUint64) + require.Empty(t, migErr) + + events := res.Ctx.EventManager().Events() + + hadCyber1 := false + + for _, e := range events { + if e.Type == "wasm-cyber1" { + require.False(t, hadCyber1) + attrs, err := parseAndDecryptAttributes(e.Attributes, res.Nonce, false) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🦄"}, + {Key: "attr2", Value: "🌈"}, + }, + attrs, + ) + + hadCyber1 = true + } + } + + require.True(t, hadCyber1) + + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr3", Value: "🐙"}, + {Key: "attr4", Value: "🦄"}, + }, + }, + res.WasmEvents, + ) +} + +func TestV1SendsMixedAttributesAndEventsFromExecuteWithSubmessageWithoutReplyAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migErr) + nonce, ctx, _, logs, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_mixed_attributes_and_events_with_submessage":{"id":0}}`, true, true, defaultGasForTests, 0) + require.Empty(t, err) + + events := ctx.EventManager().Events() + + hadCyber1 := false + hadCyber2 := false + + for _, e := range events { + if e.Type == "wasm-cyber1" { + require.False(t, hadCyber1) + attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🦄"}, + {Key: "attr2", Value: "🌈"}, + }, + attrs, + ) + + hadCyber1 = true + } + + if e.Type == "wasm-cyber2" { + require.False(t, hadCyber2) + attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr5", Value: "🐙"}, + {Key: "attr6", Value: "🦄"}, + }, + attrs, + ) + + hadCyber2 = true + } + } + + require.True(t, hadCyber1) + require.True(t, hadCyber2) + + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr3", Value: "🐙"}, + {Key: "attr4", Value: "🦄"}, + }, + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr7", Value: "😅"}, + {Key: "attr8", Value: "🦄"}, + }, + }, + logs, + ) +} + +func TestV1SendsMixedAttributesAndEventsFromExecuteWithSubmessageWithoutReplyDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + res, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"add_mixed_attributes_and_events_with_submessage":{"id":0}}`, true, true, math.MaxUint64) + require.Empty(t, migErr) + + events := res.Ctx.EventManager().Events() + + hadCyber1 := false + hadCyber2 := false + + for _, e := range events { + if e.Type == "wasm-cyber1" { + require.False(t, hadCyber1) + attrs, err := parseAndDecryptAttributes(e.Attributes, res.Nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🦄"}, + {Key: "attr2", Value: "🌈"}, + }, + attrs, + ) + + hadCyber1 = true + } + + if e.Type == "wasm-cyber2" { + require.False(t, hadCyber2) + attrs, err := parseAndDecryptAttributes(e.Attributes, res.Nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr5", Value: "🐙"}, + {Key: "attr6", Value: "🦄"}, + }, + attrs, + ) + + hadCyber2 = true + } + } + + require.True(t, hadCyber1) + require.True(t, hadCyber2) + + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr3", Value: "🐙"}, + {Key: "attr4", Value: "🦄"}, + }, + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr7", Value: "😅"}, + {Key: "attr8", Value: "🦄"}, + }, + }, + res.WasmEvents, + ) +} + +func TestV1SendsMixedAttributesAndEventsFromExecuteWithSubmessageWithReplyAfterMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, true, true, math.MaxUint64) + require.Empty(t, migErr) + nonce, ctx, _, logs, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"add_mixed_attributes_and_events_with_submessage":{"id":2500}}`, true, true, defaultGasForTests, 0) + require.Empty(t, err) + + events := ctx.EventManager().Events() + + hadCyber1 := false + hadCyber2 := false + hadCyber3 := false + + for _, e := range events { + if e.Type == "wasm-cyber1" { + require.False(t, hadCyber1) + attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🦄"}, + {Key: "attr2", Value: "🌈"}, + }, + attrs, + ) + + hadCyber1 = true + } + + if e.Type == "wasm-cyber2" { + require.False(t, hadCyber2) + attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr5", Value: "🐙"}, + {Key: "attr6", Value: "🦄"}, + }, + attrs, + ) + + hadCyber2 = true + } + + if e.Type == "wasm-cyber3" { + require.False(t, hadCyber3) + attrs, err := parseAndDecryptAttributes(e.Attributes, nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr9", Value: "🤯"}, + {Key: "attr10", Value: "🤟"}, + }, + attrs, + ) + + hadCyber3 = true + } + } + + require.True(t, hadCyber1) + require.True(t, hadCyber2) + require.True(t, hadCyber3) + + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr3", Value: "🐙"}, + {Key: "attr4", Value: "🦄"}, + }, + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr7", Value: "😅"}, + {Key: "attr8", Value: "🦄"}, + }, + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr11", Value: "😉"}, + {Key: "attr12", Value: "😊"}, + }, + }, + logs, + ) +} + +func TestV1SendsMixedAttributesAndEventsFromExecuteWithSubmessageWithReplyDuringMigrate(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + res, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"add_mixed_attributes_and_events_with_submessage":{"id":2500}}`, true, true, math.MaxUint64) + require.Empty(t, migErr) + + events := res.Ctx.EventManager().Events() + + hadCyber1 := false + hadCyber2 := false + hadCyber3 := false + + for _, e := range events { + if e.Type == "wasm-cyber1" { + require.False(t, hadCyber1) + attrs, err := parseAndDecryptAttributes(e.Attributes, res.Nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr1", Value: "🦄"}, + {Key: "attr2", Value: "🌈"}, + }, + attrs, + ) + + hadCyber1 = true + } + + if e.Type == "wasm-cyber2" { + require.False(t, hadCyber2) + attrs, err := parseAndDecryptAttributes(e.Attributes, res.Nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr5", Value: "🐙"}, + {Key: "attr6", Value: "🦄"}, + }, + attrs, + ) + + hadCyber2 = true + } + + if e.Type == "wasm-cyber3" { + require.False(t, hadCyber3) + attrs, err := parseAndDecryptAttributes(e.Attributes, res.Nonce, true) + require.Empty(t, err) + + requireLogAttributes(t, + []v010types.LogAttribute{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr9", Value: "🤯"}, + {Key: "attr10", Value: "🤟"}, + }, + attrs, + ) + + hadCyber3 = true + } + } + + require.True(t, hadCyber1) + require.True(t, hadCyber2) + require.True(t, hadCyber3) + + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr3", Value: "🐙"}, + {Key: "attr4", Value: "🦄"}, + }, + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr7", Value: "😅"}, + {Key: "attr8", Value: "🦄"}, + }, + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "attr11", Value: "😉"}, + {Key: "attr12", Value: "😊"}, + }, + }, + res.WasmEvents, + ) +} diff --git a/x/compute/internal/keeper/testdata/v1-contract-v2.wasm b/x/compute/internal/keeper/testdata/v1-contract-v2.wasm index 13c05d8463544e159a0c1231ced80801b03adcca..c275c274718598dd4ded0c78e8a42948b0b3683b 100755 GIT binary patch delta 127 zcmWN=%?*Mu0D#f7QdCd``Bj;K$(*2PFin`Cd-Ook0lf9xEm(r@CC@r-ot}*_(wt1P usU-;Me?fgSA=f=Brabe)D>LT2@y>z|maO<>&4w*I_8j=)n;*Z&arz(GrbEsE delta 127 zcmWN=%?*Mu7=Yn?Kn1Jvs|ex*PR0bBku+g~?!keC0l4+tEm(s0Nglflb{R$^CNQCi uR`qux+vHTQMdrgRUKlgsm6|u+`C!V7ISZDo_~eT<-)z|O!)`nL_qU(e*h9 Date: Tue, 4 Jul 2023 22:18:55 +0300 Subject: [PATCH 064/164] More migrate/update admin tests - TestCannotChangeAdminIfNotAdmin - TestAdminCanChangeAdmin - TestFailMigrateAndChangeAfterClearAdmin - TestFailMigrateAndChangeAdminByOldAdmin - TestOldAdminCanChangeAdminByPassingOldProof - TestOldAdminCanMigrateChangeAdminByPassingOldProof --- .../keeper/secret_contracts_migrate_test.go | 304 +++++++++++++++ .../keeper/secret_contracts_utils_test.go | 357 ++++++++++++++++++ x/compute/internal/keeper/test_common.go | 40 +- 3 files changed, 699 insertions(+), 2 deletions(-) diff --git a/x/compute/internal/keeper/secret_contracts_migrate_test.go b/x/compute/internal/keeper/secret_contracts_migrate_test.go index a9f16c223..041a078f2 100644 --- a/x/compute/internal/keeper/secret_contracts_migrate_test.go +++ b/x/compute/internal/keeper/secret_contracts_migrate_test.go @@ -6381,3 +6381,307 @@ func TestV1SendsMixedAttributesAndEventsFromExecuteWithSubmessageWithReplyDuring res.WasmEvents, ) } + +func TestCannotChangeAdminIfNotAdmin(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, walletB, privKeyB := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + t.Run("update: not admin", func(t *testing.T) { + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + info := keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, walletA.String()) + + _, updateErr := updateAdminHelper(t, keeper, ctx, contractAddress, walletB, privKeyB, walletA, defaultGasForTests) + + require.Equal(t, updateErr.Error(), "caller is not the admin: unauthorized") + }) + + t.Run("update: null admin", func(t *testing.T) { + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + info := keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, "") + + _, updateErr := updateAdminHelper(t, keeper, ctx, contractAddress, walletB, privKeyB, walletA, defaultGasForTests) + + require.Equal(t, updateErr.Error(), "caller is not the admin: unauthorized") + }) + + t.Run("clear: not admin", func(t *testing.T) { + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + info := keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, walletA.String()) + + _, updateErr := updateAdminHelper(t, keeper, ctx, contractAddress, walletB, privKeyB, nil, defaultGasForTests) + + require.Equal(t, updateErr.Error(), "caller is not the admin: unauthorized") + }) + + t.Run("clear: null admin", func(t *testing.T) { + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, nil, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + info := keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, "") + + _, updateErr := updateAdminHelper(t, keeper, ctx, contractAddress, walletB, privKeyB, nil, defaultGasForTests) + + require.Equal(t, updateErr.Error(), "caller is not the admin: unauthorized") + }) +} + +func TestAdminCanChangeAdmin(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, walletB, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + t.Run("update", func(t *testing.T) { + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + info := keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, walletA.String()) + + _, updateErr := updateAdminHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, walletB, defaultGasForTests) + require.Nil(t, updateErr) + + info = keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, walletB.String()) + }) + + t.Run("clear", func(t *testing.T) { + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + info := keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, walletA.String()) + + _, updateErr := updateAdminHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, nil, defaultGasForTests) + require.Nil(t, updateErr) + + info = keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, "") + }) +} + +func TestFailMigrateAndChangeAfterClearAdmin(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, walletB, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + info := keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, walletA.String()) + + _, updateErr := updateAdminHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, nil, defaultGasForTests) + require.Nil(t, updateErr) + + info = keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, "") + + t.Run("migrate", func(t *testing.T) { + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, false, true, math.MaxUint64, 0) + require.Contains(t, migErr.Error(), "requires migrate from admin: migrate contract failed") + }) + + t.Run("update", func(t *testing.T) { + _, updateErr = updateAdminHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, walletB, defaultGasForTests) + require.Equal(t, updateErr.Error(), "caller is not the admin: unauthorized") + }) + + t.Run("clear", func(t *testing.T) { + _, updateErr = updateAdminHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, nil, defaultGasForTests) + require.Equal(t, updateErr.Error(), "caller is not the admin: unauthorized") + }) +} + +func TestFailMigrateAndChangeAdminByOldAdmin(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, walletB, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + info := keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, walletA.String()) + + _, updateErr := updateAdminHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, walletB, defaultGasForTests) + require.Nil(t, updateErr) + + info = keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, walletB.String()) + + t.Run("migrate", func(t *testing.T) { + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migErr := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, false, true, math.MaxUint64, 0) + require.Contains(t, migErr.Error(), "requires migrate from admin: migrate contract failed") + }) + + t.Run("update", func(t *testing.T) { + _, updateErr = updateAdminHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, walletB, defaultGasForTests) + require.Equal(t, updateErr.Error(), "caller is not the admin: unauthorized") + }) + + t.Run("clear", func(t *testing.T) { + _, updateErr = updateAdminHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, nil, defaultGasForTests) + require.Equal(t, updateErr.Error(), "caller is not the admin: unauthorized") + }) +} + +func TestOldAdminCanChangeAdminByPassingOldProof(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, walletB, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + t.Run("update", func(t *testing.T) { + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + info := keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, walletA.String()) + + oldAdminProof := info.AdminProof + + _, updateErr := updateAdminHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, walletB, defaultGasForTests) + require.Nil(t, updateErr) + + info = keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, walletB.String()) + + _, updateErr = fakeUpdateAdminHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, walletA, defaultGasForTests, oldAdminProof) + require.Nil(t, updateErr) + + info = keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, walletA.String()) + }) + + t.Run("clear", func(t *testing.T) { + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + info := keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, walletA.String()) + + oldAdminProof := info.AdminProof + + _, updateErr := updateAdminHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, walletB, defaultGasForTests) + require.Nil(t, updateErr) + + info = keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, walletB.String()) + + _, updateErr = fakeUpdateAdminHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, nil, defaultGasForTests, oldAdminProof) + require.Nil(t, updateErr) + + info = keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, "") + }) + + t.Run("update after clear", func(t *testing.T) { + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + info := keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, walletA.String()) + + oldAdminProof := info.AdminProof + + _, updateErr := updateAdminHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, nil, defaultGasForTests) + require.Nil(t, updateErr) + + info = keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, "") + + _, updateErr = fakeUpdateAdminHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, walletA, defaultGasForTests, oldAdminProof) + require.Nil(t, updateErr) + + info = keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, walletA.String()) + }) + + t.Run("clear after clear", func(t *testing.T) { + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + info := keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, walletA.String()) + + oldAdminProof := info.AdminProof + + _, updateErr := updateAdminHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, nil, defaultGasForTests) + require.Nil(t, updateErr) + + info = keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, "") + + _, updateErr = fakeUpdateAdminHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, nil, defaultGasForTests, oldAdminProof) + require.Nil(t, updateErr) + + info = keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, "") + }) +} + +func TestOldAdminCanMigrateChangeAdminByPassingOldProof(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, walletB, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + t.Run("migrate", func(t *testing.T) { + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + info := keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, walletA.String()) + + oldAdminProof := info.AdminProof + + _, updateErr := updateAdminHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, walletB, defaultGasForTests) + require.Nil(t, updateErr) + + info = keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, walletB.String()) + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migErr := fakeMigrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, false, true, math.MaxUint64, oldAdminProof) + require.Empty(t, migErr) + + // admin is still walletB + info = keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, walletB.String()) + + // but code is migrated + history := keeper.GetContractHistory(ctx, contractAddress) + require.Len(t, history, 2) + require.Equal(t, history[0].CodeID, codeID) + require.Equal(t, history[1].CodeID, newCodeId) + }) + + t.Run("migrate after clear", func(t *testing.T) { + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + info := keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, walletA.String()) + + oldAdminProof := info.AdminProof + + _, updateErr := updateAdminHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, nil, defaultGasForTests) + require.Nil(t, updateErr) + + info = keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, "") + + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migErr := fakeMigrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, false, true, math.MaxUint64, oldAdminProof) + require.Empty(t, migErr) + + // admin is still nil + info = keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, "") + + // but code is migrated + history := keeper.GetContractHistory(ctx, contractAddress) + require.Len(t, history, 2) + require.Equal(t, history[0].CodeID, codeID) + require.Equal(t, history[1].CodeID, newCodeId) + }) +} diff --git a/x/compute/internal/keeper/secret_contracts_utils_test.go b/x/compute/internal/keeper/secret_contracts_utils_test.go index 45d3bb1df..18950c02e 100644 --- a/x/compute/internal/keeper/secret_contracts_utils_test.go +++ b/x/compute/internal/keeper/secret_contracts_utils_test.go @@ -7,9 +7,12 @@ import ( "fmt" "os" "regexp" + "strconv" "strings" "testing" + "time" + "github.com/cosmos/cosmos-sdk/telemetry" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" stypes "github.com/cosmos/cosmos-sdk/store/types" @@ -24,6 +27,8 @@ import ( cosmwasm "github.com/scrtlabs/SecretNetwork/go-cosmwasm/types" v010cosmwasm "github.com/scrtlabs/SecretNetwork/go-cosmwasm/types/v010" + v010wasmTypes "github.com/scrtlabs/SecretNetwork/go-cosmwasm/types/v010" + v1wasmTypes "github.com/scrtlabs/SecretNetwork/go-cosmwasm/types/v1" "github.com/scrtlabs/SecretNetwork/x/compute/internal/types" ) @@ -875,3 +880,355 @@ func migrateHelper( return result, nil } + +func updateAdminHelper( + t *testing.T, + keeper Keeper, + ctx sdk.Context, + contractAddress sdk.AccAddress, + sender sdk.AccAddress, + senderPrivkey crypto.PrivKey, + newAdmin sdk.AccAddress, + gas uint64, +) (UpdateAdminResult, error) { + // create new ctx with the same storage and a gas limit + // this is to reset the event manager, so we won't get + // events from past calls + gasMeter := &WasmCounterGasMeter{0, sdk.NewGasMeter(gas)} + ctx = sdk.NewContext( + ctx.MultiStore(), + ctx.BlockHeader(), + ctx.IsCheckTx(), + log.NewNopLogger(), + ).WithGasMeter(gasMeter) + + if newAdmin.Empty() { + ctx = prepareClearAdminSignedTx(t, keeper, ctx, contractAddress.String(), sender, senderPrivkey) + } else { + ctx = prepareUpdateAdminSignedTx(t, keeper, ctx, contractAddress.String(), sender, senderPrivkey, newAdmin) + } + + gasBefore := ctx.GasMeter().GasConsumed() + err := keeper.UpdateContractAdmin(ctx, contractAddress, sender, newAdmin) + gasAfter := ctx.GasMeter().GasConsumed() + gasUsed := gasAfter - gasBefore + + return UpdateAdminResult{ + Ctx: ctx, + GasUsed: gasUsed, + }, err +} + +func fakeUpdateContractAdmin(ctx sdk.Context, k Keeper, contractAddress, caller, newAdmin sdk.AccAddress, fakeAdminProof []byte) error { + defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "update-contract-admin") + ctx.GasMeter().ConsumeGas(types.InstanceCost, "Loading CosmWasm module: update-contract-admin") + + contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddress) + if err != nil { + return err + } + + signBytes, signMode, modeInfoBytes, pkBytes, signerSig, err := k.GetTxInfo(ctx, caller) + if err != nil { + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, err.Error()) + } + + verificationInfo := types.NewVerificationInfo(signBytes, signMode, modeInfoBytes, pkBytes, signerSig, nil) + + contractKey, err := k.GetContractKey(ctx, contractAddress) + if err != nil { + return err + } + + env := types.NewEnv(ctx, caller, sdk.Coins{}, contractAddress, contractKey, nil) + + // prepare querier + // TODO: this is unnecessary, get rid of this + querier := QueryHandler{ + Ctx: ctx, + Plugins: k.queryPlugins, + Caller: contractAddress, + } + + // instantiate wasm contract + gas := gasForContract(ctx) + + newAdminProof, updateAdminErr := k.wasmer.UpdateAdmin(codeInfo.CodeHash, env, prefixStore, cosmwasmAPI, querier, gasMeter(ctx), gas, verificationInfo, caller, fakeAdminProof) + + if updateAdminErr != nil { + return updateAdminErr + } + + contractInfo.Admin = newAdmin.String() + contractInfo.AdminProof = newAdminProof + k.setContractInfo(ctx, contractAddress, &contractInfo) + + ctx.EventManager().EmitEvent(sdk.NewEvent( + types.EventTypeUpdateContractAdmin, + sdk.NewAttribute(types.AttributeKeyContractAddr, contractAddress.String()), + sdk.NewAttribute(types.AttributeKeyNewAdmin, newAdmin.String()), + )) + + return nil +} + +func fakeUpdateAdminHelper( + t *testing.T, + keeper Keeper, + ctx sdk.Context, + contractAddress sdk.AccAddress, + sender sdk.AccAddress, + senderPrivkey crypto.PrivKey, + newAdmin sdk.AccAddress, + gas uint64, + fakeAdminProof []byte, +) (UpdateAdminResult, error) { + // create new ctx with the same storage and a gas limit + // this is to reset the event manager, so we won't get + // events from past calls + gasMeter := &WasmCounterGasMeter{0, sdk.NewGasMeter(gas)} + ctx = sdk.NewContext( + ctx.MultiStore(), + ctx.BlockHeader(), + ctx.IsCheckTx(), + log.NewNopLogger(), + ).WithGasMeter(gasMeter) + + if newAdmin.Empty() { + ctx = prepareClearAdminSignedTx(t, keeper, ctx, contractAddress.String(), sender, senderPrivkey) + } else { + ctx = prepareUpdateAdminSignedTx(t, keeper, ctx, contractAddress.String(), sender, senderPrivkey, newAdmin) + } + + gasBefore := ctx.GasMeter().GasConsumed() + err := fakeUpdateContractAdmin(ctx, keeper, contractAddress, sender, newAdmin, fakeAdminProof) + gasAfter := ctx.GasMeter().GasConsumed() + gasUsed := gasAfter - gasBefore + + return UpdateAdminResult{ + Ctx: ctx, + GasUsed: gasUsed, + }, err +} + +func fakeMigrate(ctx sdk.Context, k Keeper, contractAddress sdk.AccAddress, caller sdk.AccAddress, newCodeID uint64, msg []byte, fakeAdminProof []byte) ([]byte, error) { + defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "migrate") + ctx.GasMeter().ConsumeGas(types.InstanceCost, "Loading CosmWasm module: migrate") + + signBytes, signMode, modeInfoBytes, pkBytes, signerSig, err := k.GetTxInfo(ctx, caller) + if err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, err.Error()) + } + + verificationInfo := types.NewVerificationInfo(signBytes, signMode, modeInfoBytes, pkBytes, signerSig, nil) + + contractInfo, _, prefixStore, err := k.contractInstance(ctx, contractAddress) + if err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, sdkerrors.Wrap(err, "unknown contract").Error()) + } + + newCodeInfo, err := k.GetCodeInfo(ctx, newCodeID) + if err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, sdkerrors.Wrap(err, "unknown code").Error()) + } + + // check for IBC flag + switch report, err := k.wasmer.AnalyzeCode(newCodeInfo.CodeHash); { + case err != nil: + return nil, sdkerrors.Wrap(types.ErrMigrationFailed, err.Error()) + case !report.HasIBCEntryPoints && contractInfo.IBCPortID != "": + // prevent update of ibc contract to non ibc contract + return nil, sdkerrors.Wrap(types.ErrMigrationFailed, "requires ibc callbacks") + case report.HasIBCEntryPoints && contractInfo.IBCPortID == "": + // add ibc port + ibcPort, err := k.ensureIbcPort(ctx, contractAddress) + if err != nil { + return nil, err + } + contractInfo.IBCPortID = ibcPort + } + + contractKey, err := k.GetContractKey(ctx, contractAddress) + if err != nil { + return nil, err + } + + random := k.GetRandomSeed(ctx, ctx.BlockHeight()) + + env := types.NewEnv(ctx, caller, sdk.Coins{}, contractAddress, contractKey, random) + + // prepare querier + querier := QueryHandler{ + Ctx: ctx, + Plugins: k.queryPlugins, + Caller: contractAddress, + } + + // instantiate wasm contract + gas := gasForContract(ctx) + + response, newContractKey, newContractKeyProof, gasUsed, migrateErr := k.wasmer.Migrate(newCodeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, gasMeter(ctx), gas, verificationInfo, caller, fakeAdminProof) + consumeGas(ctx, gasUsed) + + if migrateErr != nil { + var result []byte + var jsonError error + switch res := response.(type) { //nolint:gocritic + case v1wasmTypes.DataWithInternalReplyInfo: + result, jsonError = json.Marshal(res) + if jsonError != nil { + return nil, sdkerrors.Wrap(jsonError, "couldn't marshal internal reply info") + } + } + + return result, sdkerrors.Wrap(types.ErrMigrationFailed, migrateErr.Error()) + } + + // update contract key with new one + k.SetContractKey(ctx, contractAddress, &types.ContractKey{ + OgContractKey: contractKey.OgContractKey, + CurrentContractKey: newContractKey, + CurrentContractKeyProof: newContractKeyProof, + }) + + // delete old secondary index entry + k.removeFromContractCodeSecondaryIndex(ctx, contractAddress, k.getLastContractHistoryEntry(ctx, contractAddress)) + // persist migration updates + historyEntry := contractInfo.AddMigration(ctx, newCodeID, msg) + k.appendToContractHistory(ctx, contractAddress, historyEntry) + k.addToContractCodeSecondaryIndex(ctx, contractAddress, historyEntry) + + contractInfo.CodeID = newCodeID + k.setContractInfo(ctx, contractAddress, &contractInfo) + + ctx.EventManager().EmitEvent(sdk.NewEvent( + types.EventTypeMigrate, + sdk.NewAttribute(types.AttributeKeyCodeID, strconv.FormatUint(newCodeID, 10)), + sdk.NewAttribute(types.AttributeKeyContractAddr, contractAddress.String()), + )) + + switch res := response.(type) { + case *v010wasmTypes.HandleResponse: + subMessages, err := V010MsgsToV1SubMsgs(contractAddress.String(), res.Messages) + if err != nil { + return nil, sdkerrors.Wrap(err, "couldn't convert v0.10 messages to v1 messages") + } + + data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, subMessages, res.Log, []v1wasmTypes.Event{}, res.Data, msg, verificationInfo) + if err != nil { + return nil, sdkerrors.Wrap(err, "dispatch") + } + + return data, nil + case *v1wasmTypes.Response: + data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res.Messages, res.Attributes, res.Events, res.Data, msg, verificationInfo) + if err != nil { + return nil, sdkerrors.Wrap(err, "dispatch") + } + + return data, nil + default: + return nil, sdkerrors.Wrap(types.ErrMigrationFailed, fmt.Sprintf("cannot detect response type: %+v", res)) + } +} + +func fakeMigrateHelper( + t *testing.T, + keeper Keeper, + ctx sdk.Context, + newCodeId uint64, + contractAddress sdk.AccAddress, + txSender sdk.AccAddress, + senderPrivKey crypto.PrivKey, + migrateMsg string, + isErrorEncrypted bool, + isV1Contract bool, + gas uint64, + fakeAdminProof []byte, + wasmCallCount ...int64, +) (MigrateResult, *ErrorResult) { + codeInfo, err := keeper.GetCodeInfo(ctx, newCodeId) + require.NoError(t, err) + + hashStr := hex.EncodeToString(codeInfo.CodeHash) + + secretMsg := types.SecretMsg{ + CodeHash: []byte(hashStr), + Msg: []byte(migrateMsg), + } + + migrateMsgBz, err := wasmCtx.Encrypt(secretMsg.Serialize()) + require.NoError(t, err) + + // create new ctx with the same storage and a gas limit + // this is to reset the event manager, so we won't get + // events from past calls + gasMeter := &WasmCounterGasMeter{0, sdk.NewGasMeter(gas)} + ctx = sdk.NewContext( + ctx.MultiStore(), + ctx.BlockHeader(), + ctx.IsCheckTx(), + log.NewNopLogger(), + ).WithGasMeter(gasMeter) + + ctx = prepareMigrateSignedTx(t, keeper, ctx, contractAddress.String(), txSender, senderPrivKey, migrateMsgBz, newCodeId) + + // reset value before test + keeper.LastMsgManager.SetMarker(false) + + // simulate the check in baseapp + if keeper.LastMsgManager.GetMarker() { + errResult := ErrorResult{ + Generic: sdkerrors.Wrap(sdkerrors.ErrLastTx, "Error"), + } + return MigrateResult{}, &errResult + } + + nonce := migrateMsgBz[0:32] + + gasBefore := ctx.GasMeter().GasConsumed() + execResult, err := fakeMigrate(ctx, keeper, contractAddress, txSender, newCodeId, migrateMsgBz, fakeAdminProof) + gasAfter := ctx.GasMeter().GasConsumed() + gasUsed := gasAfter - gasBefore + + if len(wasmCallCount) == 0 { + // default, just check that at least 1 call happened + require.NotZero(t, gasMeter.GetWasmCounter(), err) + } else { + require.Equal(t, uint64(wasmCallCount[0]), gasMeter.GetWasmCounter(), err) + } + + if err != nil { + result := MigrateResult{ + Nonce: nil, + Ctx: ctx, + Data: nil, + WasmEvents: nil, + GasUsed: gasUsed, + } + + errResult := ErrorResult{ + Generic: err, + } + cwErr := extractInnerError(t, err, nonce, isErrorEncrypted, isV1Contract) + errResult.CosmWasm = &cwErr + + return result, &errResult + } + + // wasmEvents come from all the callbacks as well + wasmEvents := tryDecryptWasmEvents(ctx, nonce) + + // Data is the output of only the first call + data := getDecryptedData(t, execResult, nonce) + + result := MigrateResult{ + Nonce: nonce, + Ctx: ctx, + Data: data, + WasmEvents: wasmEvents, + GasUsed: gasUsed, + } + + return result, nil +} diff --git a/x/compute/internal/keeper/test_common.go b/x/compute/internal/keeper/test_common.go index 73a593928..ad5b77421 100644 --- a/x/compute/internal/keeper/test_common.go +++ b/x/compute/internal/keeper/test_common.go @@ -154,6 +154,11 @@ type MigrateResult struct { GasUsed uint64 } +type UpdateAdminResult struct { + Ctx sdk.Context + GasUsed uint64 +} + type ExecResult struct { Nonce []byte Ctx sdk.Context @@ -713,13 +718,44 @@ func prepareMigrateSignedTx(t *testing.T, keeper Keeper, ctx sdk.Context, contra creatorAcc, err := ante.GetSignerAcc(ctx, keeper.accountKeeper, creator) require.NoError(t, err) - initMsg := wasmtypes.MsgMigrateContract{ + migrateMsg := wasmtypes.MsgMigrateContract{ Sender: creator.String(), CodeID: codeID, Contract: contractAddress, Msg: encMsg, } - newTx := NewTestTx(&initMsg, creatorAcc, privKey) + newTx := NewTestTx(&migrateMsg, creatorAcc, privKey) + txBytes, err := newTx.Marshal() + require.NoError(t, err) + + return ctx.WithTxBytes(txBytes) +} + +func prepareUpdateAdminSignedTx(t *testing.T, keeper Keeper, ctx sdk.Context, contractAddress string, sender sdk.AccAddress, privKey crypto.PrivKey, newAdmin sdk.AccAddress) sdk.Context { + senderAccount, err := ante.GetSignerAcc(ctx, keeper.accountKeeper, sender) + require.NoError(t, err) + + sdkMsg := wasmtypes.MsgUpdateAdmin{ + Sender: sender.String(), + Contract: contractAddress, + NewAdmin: newAdmin.String(), + } + newTx := NewTestTx(&sdkMsg, senderAccount, privKey) + txBytes, err := newTx.Marshal() + require.NoError(t, err) + + return ctx.WithTxBytes(txBytes) +} + +func prepareClearAdminSignedTx(t *testing.T, keeper Keeper, ctx sdk.Context, contractAddress string, sender sdk.AccAddress, privKey crypto.PrivKey) sdk.Context { + senderAccount, err := ante.GetSignerAcc(ctx, keeper.accountKeeper, sender) + require.NoError(t, err) + + sdkMsg := wasmtypes.MsgClearAdmin{ + Sender: sender.String(), + Contract: contractAddress, + } + newTx := NewTestTx(&sdkMsg, senderAccount, privKey) txBytes, err := newTx.Marshal() require.NoError(t, err) From 3171ca5ec259fa77069d98366ad2ffe5a51b412d Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 4 Jul 2023 23:23:33 +0300 Subject: [PATCH 065/164] Test fake admin vlaues passed to the enclave TestEnclaveFailsAdminIsNotSender --- .../keeper/secret_contracts_migrate_test.go | 104 +++++++++++++++++- .../keeper/secret_contracts_utils_test.go | 33 ++++-- 2 files changed, 123 insertions(+), 14 deletions(-) diff --git a/x/compute/internal/keeper/secret_contracts_migrate_test.go b/x/compute/internal/keeper/secret_contracts_migrate_test.go index 041a078f2..83a69a3a2 100644 --- a/x/compute/internal/keeper/secret_contracts_migrate_test.go +++ b/x/compute/internal/keeper/secret_contracts_migrate_test.go @@ -6548,7 +6548,7 @@ func TestOldAdminCanChangeAdminByPassingOldProof(t *testing.T) { info = keeper.GetContractInfo(ctx, contractAddress) require.Equal(t, info.Admin, walletB.String()) - _, updateErr = fakeUpdateAdminHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, walletA, defaultGasForTests, oldAdminProof) + _, updateErr = fakeUpdateAdminHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, walletA, defaultGasForTests, walletA, oldAdminProof) require.Nil(t, updateErr) info = keeper.GetContractInfo(ctx, contractAddress) @@ -6570,7 +6570,7 @@ func TestOldAdminCanChangeAdminByPassingOldProof(t *testing.T) { info = keeper.GetContractInfo(ctx, contractAddress) require.Equal(t, info.Admin, walletB.String()) - _, updateErr = fakeUpdateAdminHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, nil, defaultGasForTests, oldAdminProof) + _, updateErr = fakeUpdateAdminHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, nil, defaultGasForTests, walletA, oldAdminProof) require.Nil(t, updateErr) info = keeper.GetContractInfo(ctx, contractAddress) @@ -6592,7 +6592,7 @@ func TestOldAdminCanChangeAdminByPassingOldProof(t *testing.T) { info = keeper.GetContractInfo(ctx, contractAddress) require.Equal(t, info.Admin, "") - _, updateErr = fakeUpdateAdminHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, walletA, defaultGasForTests, oldAdminProof) + _, updateErr = fakeUpdateAdminHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, walletA, defaultGasForTests, walletA, oldAdminProof) require.Nil(t, updateErr) info = keeper.GetContractInfo(ctx, contractAddress) @@ -6614,7 +6614,7 @@ func TestOldAdminCanChangeAdminByPassingOldProof(t *testing.T) { info = keeper.GetContractInfo(ctx, contractAddress) require.Equal(t, info.Admin, "") - _, updateErr = fakeUpdateAdminHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, nil, defaultGasForTests, oldAdminProof) + _, updateErr = fakeUpdateAdminHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, nil, defaultGasForTests, walletA, oldAdminProof) require.Nil(t, updateErr) info = keeper.GetContractInfo(ctx, contractAddress) @@ -6641,7 +6641,7 @@ func TestOldAdminCanMigrateChangeAdminByPassingOldProof(t *testing.T) { require.Equal(t, info.Admin, walletB.String()) newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) - _, migErr := fakeMigrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, false, true, math.MaxUint64, oldAdminProof) + _, migErr := fakeMigrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, false, true, math.MaxUint64, walletA, oldAdminProof) require.Empty(t, migErr) // admin is still walletB @@ -6671,7 +6671,7 @@ func TestOldAdminCanMigrateChangeAdminByPassingOldProof(t *testing.T) { require.Equal(t, info.Admin, "") newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) - _, migErr := fakeMigrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, false, true, math.MaxUint64, oldAdminProof) + _, migErr := fakeMigrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"nop":{}}`, false, true, math.MaxUint64, walletA, oldAdminProof) require.Empty(t, migErr) // admin is still nil @@ -6685,3 +6685,95 @@ func TestOldAdminCanMigrateChangeAdminByPassingOldProof(t *testing.T) { require.Equal(t, history[1].CodeID, newCodeId) }) } + +func TestEnclaveFailsAdminIsNotSender(t *testing.T) { + ctx, keeper, codeID, _, walletA, privkeyA, walletB, privkeyB := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + t.Run("migrate fails msg verify params", func(t *testing.T) { + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletB, privkeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + // B is the admin + info := keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, walletB.String()) + + bAdminProof := info.AdminProof + + // now A is the admin + _, updateErr := updateAdminHelper(t, keeper, ctx, contractAddress, walletB, privkeyB, walletA, defaultGasForTests) + require.Nil(t, updateErr) + + info = keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, walletA.String()) + + // A is the admin but B is the sender + // B passes old B's proof which is valid and should pass the proof check + // however the sender==admin check later on should fail + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migErr := fakeMigrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletB, privkeyB, `{"nop":{}}`, false, true, math.MaxUint64, walletA, bAdminProof) + require.Contains(t, migErr.Error(), "Enclave: failed to verify transaction signature: migrate contract failed") + }) + + t.Run("migrate fails admin proof check", func(t *testing.T) { + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privkeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + info := keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, walletA.String()) + + // A is the admin but B is the sender + // B passes A's proof + newCodeId, _ := uploadCode(ctx, t, keeper, TestContractPaths[v1MigratedContract], walletA) + _, migErr := fakeMigrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletB, privkeyB, `{"nop":{}}`, false, true, math.MaxUint64, walletA, info.AdminProof) + require.Contains(t, migErr.Error(), "Enclave: failed to validate transaction: migrate contract failed") + }) + + t.Run("change fails msg verify params", func(t *testing.T) { + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletB, privkeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + // B is the admin + info := keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, walletB.String()) + + bAdminProof := info.AdminProof + + // now A is the admin + _, updateErr := updateAdminHelper(t, keeper, ctx, contractAddress, walletB, privkeyB, walletA, defaultGasForTests) + require.Nil(t, updateErr) + + info = keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, walletA.String()) + + // A is the admin but B is the sender + // B passes old B's proof which is valid and should pass the proof check + // however the sender==admin check later on should fail + t.Run("update", func(t *testing.T) { + _, updateErr = fakeUpdateAdminHelper(t, keeper, ctx, contractAddress, walletB, privkeyB, walletB, math.MaxUint64, walletA, bAdminProof) + require.Contains(t, updateErr.Error(), "Enclave: failed to verify transaction signature") + }) + t.Run("clear", func(t *testing.T) { + _, updateErr = fakeUpdateAdminHelper(t, keeper, ctx, contractAddress, walletB, privkeyB, nil, math.MaxUint64, walletA, bAdminProof) + require.Contains(t, updateErr.Error(), "Enclave: failed to verify transaction signature") + }) + }) + + t.Run("change fails admin proof check", func(t *testing.T) { + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, walletA, privkeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, err) + + info := keeper.GetContractInfo(ctx, contractAddress) + require.Equal(t, info.Admin, walletA.String()) + + // A is the admin but B is the sender + // B passes A's proof + t.Run("update", func(t *testing.T) { + _, updateErr := fakeUpdateAdminHelper(t, keeper, ctx, contractAddress, walletB, privkeyB, walletB, math.MaxUint64, walletA, info.AdminProof) + require.Contains(t, updateErr.Error(), "Enclave: failed to validate transaction") + }) + t.Run("clear", func(t *testing.T) { + _, updateErr := fakeUpdateAdminHelper(t, keeper, ctx, contractAddress, walletB, privkeyB, nil, math.MaxUint64, walletA, info.AdminProof) + require.Contains(t, updateErr.Error(), "Enclave: failed to validate transaction") + }) + }) +} diff --git a/x/compute/internal/keeper/secret_contracts_utils_test.go b/x/compute/internal/keeper/secret_contracts_utils_test.go index 18950c02e..2c7eda5d3 100644 --- a/x/compute/internal/keeper/secret_contracts_utils_test.go +++ b/x/compute/internal/keeper/secret_contracts_utils_test.go @@ -919,7 +919,14 @@ func updateAdminHelper( }, err } -func fakeUpdateContractAdmin(ctx sdk.Context, k Keeper, contractAddress, caller, newAdmin sdk.AccAddress, fakeAdminProof []byte) error { +func fakeUpdateContractAdmin(ctx sdk.Context, + k Keeper, + contractAddress, + caller, + newAdmin sdk.AccAddress, + adminToSend sdk.AccAddress, + adminProof []byte, +) error { defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "update-contract-admin") ctx.GasMeter().ConsumeGas(types.InstanceCost, "Loading CosmWasm module: update-contract-admin") @@ -953,7 +960,7 @@ func fakeUpdateContractAdmin(ctx sdk.Context, k Keeper, contractAddress, caller, // instantiate wasm contract gas := gasForContract(ctx) - newAdminProof, updateAdminErr := k.wasmer.UpdateAdmin(codeInfo.CodeHash, env, prefixStore, cosmwasmAPI, querier, gasMeter(ctx), gas, verificationInfo, caller, fakeAdminProof) + newAdminProof, updateAdminErr := k.wasmer.UpdateAdmin(codeInfo.CodeHash, env, prefixStore, cosmwasmAPI, querier, gasMeter(ctx), gas, verificationInfo, adminToSend, adminProof) if updateAdminErr != nil { return updateAdminErr @@ -981,7 +988,8 @@ func fakeUpdateAdminHelper( senderPrivkey crypto.PrivKey, newAdmin sdk.AccAddress, gas uint64, - fakeAdminProof []byte, + adminToSend sdk.AccAddress, + adminProof []byte, ) (UpdateAdminResult, error) { // create new ctx with the same storage and a gas limit // this is to reset the event manager, so we won't get @@ -1001,7 +1009,7 @@ func fakeUpdateAdminHelper( } gasBefore := ctx.GasMeter().GasConsumed() - err := fakeUpdateContractAdmin(ctx, keeper, contractAddress, sender, newAdmin, fakeAdminProof) + err := fakeUpdateContractAdmin(ctx, keeper, contractAddress, sender, newAdmin, adminToSend, adminProof) gasAfter := ctx.GasMeter().GasConsumed() gasUsed := gasAfter - gasBefore @@ -1011,7 +1019,15 @@ func fakeUpdateAdminHelper( }, err } -func fakeMigrate(ctx sdk.Context, k Keeper, contractAddress sdk.AccAddress, caller sdk.AccAddress, newCodeID uint64, msg []byte, fakeAdminProof []byte) ([]byte, error) { +func fakeMigrate(ctx sdk.Context, + k Keeper, + contractAddress sdk.AccAddress, + caller sdk.AccAddress, + newCodeID uint64, + msg []byte, + adminToSend sdk.AccAddress, + adminProof []byte, +) ([]byte, error) { defer telemetry.MeasureSince(time.Now(), "compute", "keeper", "migrate") ctx.GasMeter().ConsumeGas(types.InstanceCost, "Loading CosmWasm module: migrate") @@ -1067,7 +1083,7 @@ func fakeMigrate(ctx sdk.Context, k Keeper, contractAddress sdk.AccAddress, call // instantiate wasm contract gas := gasForContract(ctx) - response, newContractKey, newContractKeyProof, gasUsed, migrateErr := k.wasmer.Migrate(newCodeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, gasMeter(ctx), gas, verificationInfo, caller, fakeAdminProof) + response, newContractKey, newContractKeyProof, gasUsed, migrateErr := k.wasmer.Migrate(newCodeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, gasMeter(ctx), gas, verificationInfo, adminToSend, adminProof) consumeGas(ctx, gasUsed) if migrateErr != nil { @@ -1144,7 +1160,8 @@ func fakeMigrateHelper( isErrorEncrypted bool, isV1Contract bool, gas uint64, - fakeAdminProof []byte, + adminToSend sdk.AccAddress, + adminProof []byte, wasmCallCount ...int64, ) (MigrateResult, *ErrorResult) { codeInfo, err := keeper.GetCodeInfo(ctx, newCodeId) @@ -1187,7 +1204,7 @@ func fakeMigrateHelper( nonce := migrateMsgBz[0:32] gasBefore := ctx.GasMeter().GasConsumed() - execResult, err := fakeMigrate(ctx, keeper, contractAddress, txSender, newCodeId, migrateMsgBz, fakeAdminProof) + execResult, err := fakeMigrate(ctx, keeper, contractAddress, txSender, newCodeId, migrateMsgBz, adminToSend, adminProof) gasAfter := ctx.GasMeter().GasConsumed() gasUsed := gasAfter - gasBefore From 9f0cea7eca22e3441d8f813255208ebf00ae3e32 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 5 Jul 2023 14:55:54 +0300 Subject: [PATCH 066/164] enigma.co -> scrtlabs.com --- .../compute-tests/test-compute-contract/Cargo.toml | 2 +- cosmwasm/contracts/v010/dist/Cargo.toml | 2 +- cosmwasm/contracts/v010/gov/Cargo.toml | 2 +- cosmwasm/contracts/v010/mint/Cargo.toml | 2 +- .../v1/compute-tests/ibc-test-contract/Cargo.toml | 7 +++++-- .../contracts/v1/compute-tests/random-test/Cargo.toml | 7 ++++--- .../compute-tests/test-compute-contract-v2/Cargo.toml | 2 +- .../v1/compute-tests/test-compute-contract/Cargo.toml | 2 +- cosmwasm/contracts/v1/dist/Cargo.toml | 2 +- cosmwasm/contracts/v1/gov/Cargo.toml | 6 ++---- cosmwasm/contracts/v1/mint/Cargo.toml | 4 ++-- cosmwasm/enclaves/ffi-types/Cargo.toml | 6 +++--- cosmwasm/enclaves/shared/contract-engine/Cargo.toml | 11 +++++++---- cosmwasm/enclaves/shared/cosmos-types/Cargo.toml | 2 +- cosmwasm/packages/sgx-vm/Cargo.toml | 3 +-- integration-tests/contract-v0.10/Cargo.toml | 2 +- seed-service/src/enclaves/ffi-types/Cargo.toml | 2 +- .../src/enclaves/shared/contract-engine/Cargo.toml | 5 ++--- 18 files changed, 36 insertions(+), 33 deletions(-) diff --git a/cosmwasm/contracts/v010/compute-tests/test-compute-contract/Cargo.toml b/cosmwasm/contracts/v010/compute-tests/test-compute-contract/Cargo.toml index d2308394d..ed7262d38 100644 --- a/cosmwasm/contracts/v010/compute-tests/test-compute-contract/Cargo.toml +++ b/cosmwasm/contracts/v010/compute-tests/test-compute-contract/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "test-contract" version = "0.0.1" -authors = ["Enigma "] +authors = ["SCRT Labs "] edition = "2018" description = "A Test contract intended to use in system tests for the Secret Netowrk" license = "MIT" diff --git a/cosmwasm/contracts/v010/dist/Cargo.toml b/cosmwasm/contracts/v010/dist/Cargo.toml index cdcc82255..9ea9c3e40 100644 --- a/cosmwasm/contracts/v010/dist/Cargo.toml +++ b/cosmwasm/contracts/v010/dist/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "dist" version = "0.9.0-alpha1" -authors = ["Cash Maney "] +authors = ["Cash Maney "] publish = false edition = "2018" description = "Reflect messages to use for test cases - based on cw-mask" diff --git a/cosmwasm/contracts/v010/gov/Cargo.toml b/cosmwasm/contracts/v010/gov/Cargo.toml index bf1e26db3..47b499987 100644 --- a/cosmwasm/contracts/v010/gov/Cargo.toml +++ b/cosmwasm/contracts/v010/gov/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "gov" version = "0.9.0-alpha1" -authors = ["Cash Maney "] +authors = ["Cash Maney "] publish = false edition = "2018" description = "Reflect messages to use for test cases - based on cw-mask" diff --git a/cosmwasm/contracts/v010/mint/Cargo.toml b/cosmwasm/contracts/v010/mint/Cargo.toml index 9b43a5b40..3ae5d6df3 100644 --- a/cosmwasm/contracts/v010/mint/Cargo.toml +++ b/cosmwasm/contracts/v010/mint/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "mint" version = "0.9.0-alpha1" -authors = ["Cash Maney "] +authors = ["Cash Maney "] publish = false edition = "2018" description = "Reflect messages to use for test cases - based on cw-mask" diff --git a/cosmwasm/contracts/v1/compute-tests/ibc-test-contract/Cargo.toml b/cosmwasm/contracts/v1/compute-tests/ibc-test-contract/Cargo.toml index 4e88bb1d4..4a6bf9bce 100644 --- a/cosmwasm/contracts/v1/compute-tests/ibc-test-contract/Cargo.toml +++ b/cosmwasm/contracts/v1/compute-tests/ibc-test-contract/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "ibc" version = "0.0.1" -authors = ["Enigma "] +authors = ["SCRT Labs "] edition = "2018" description = "A Test contract intended to use in system tests for the Secret Netowrk" license = "MIT" @@ -33,7 +33,10 @@ stargate = [] ibc3 = ["stargate"] [dependencies] -cosmwasm-std = { git = "https://github.com/scrtlabs/cosmwasm", branch = "secret", features=["stargate", "ibc3"] } +cosmwasm-std = { git = "https://github.com/scrtlabs/cosmwasm", branch = "secret", features = [ + "stargate", + "ibc3" +] } cosmwasm-storage = { git = "https://github.com/scrtlabs/cosmwasm", branch = "secret" } schemars = "0.8.1" serde = { version = "1.0.114", default-features = false, features = [ diff --git a/cosmwasm/contracts/v1/compute-tests/random-test/Cargo.toml b/cosmwasm/contracts/v1/compute-tests/random-test/Cargo.toml index 54e78ff55..093f28e4a 100644 --- a/cosmwasm/contracts/v1/compute-tests/random-test/Cargo.toml +++ b/cosmwasm/contracts/v1/compute-tests/random-test/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "v1-random-test" version = "0.0.1" -authors = ["Enigma "] +authors = ["SCRT Labs "] edition = "2018" description = "A Test contract intended to use in system tests for the Secret Netowrk" license = "MIT" @@ -30,9 +30,10 @@ default = [] backtraces = ["cosmwasm-std/backtraces"] [dependencies] -cosmwasm-std = { git = "https://github.com/scrtlabs/cosmwasm", rev = "8ee395ba033c392d7170c971df97f085edaed2d9", package = "secret-cosmwasm-std", features = ["random"] } +cosmwasm-std = { git = "https://github.com/scrtlabs/cosmwasm", rev = "8ee395ba033c392d7170c971df97f085edaed2d9", package = "secret-cosmwasm-std", features = [ + "random" +] } cosmwasm-storage = { git = "https://github.com/scrtlabs/cosmwasm", rev = "8ee395ba033c392d7170c971df97f085edaed2d9", package = "secret-cosmwasm-storage" } - schemars = "0.8.1" serde = { version = "1.0.114", default-features = false, features = [ "derive", diff --git a/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Cargo.toml b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Cargo.toml index 7a48b1462..9ad1cf7f5 100644 --- a/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Cargo.toml +++ b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "v1-sanity-contract-v2" version = "0.0.1" -authors = ["Enigma "] +authors = ["SCRT Labs "] edition = "2018" description = "A Test contract intended to use in system tests for the Secret Netowrk" license = "MIT" diff --git a/cosmwasm/contracts/v1/compute-tests/test-compute-contract/Cargo.toml b/cosmwasm/contracts/v1/compute-tests/test-compute-contract/Cargo.toml index 88417dece..feba00a10 100644 --- a/cosmwasm/contracts/v1/compute-tests/test-compute-contract/Cargo.toml +++ b/cosmwasm/contracts/v1/compute-tests/test-compute-contract/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "v1-sanity-contract" version = "0.0.1" -authors = ["Enigma "] +authors = ["SCRT Labs "] edition = "2018" description = "A Test contract intended to use in system tests for the Secret Netowrk" license = "MIT" diff --git a/cosmwasm/contracts/v1/dist/Cargo.toml b/cosmwasm/contracts/v1/dist/Cargo.toml index a076501e8..492e5fb3a 100644 --- a/cosmwasm/contracts/v1/dist/Cargo.toml +++ b/cosmwasm/contracts/v1/dist/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "dist" version = "0.9.0-alpha1" -authors = ["Cash Maney "] +authors = ["Cash Maney "] publish = false edition = "2018" description = "Reflect messages to use for test cases - based on cw-mask" diff --git a/cosmwasm/contracts/v1/gov/Cargo.toml b/cosmwasm/contracts/v1/gov/Cargo.toml index 9e4fd261f..83433ad3c 100644 --- a/cosmwasm/contracts/v1/gov/Cargo.toml +++ b/cosmwasm/contracts/v1/gov/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "gov" version = "0.9.0-alpha1" -authors = ["Cash Maney "] +authors = ["Cash Maney "] publish = false edition = "2018" description = "Reflect messages to use for test cases - based on cw-mask" @@ -34,6 +34,4 @@ default = [] cosmwasm-std = { package = "secret-cosmwasm-std", version = "0.10.1" } cosmwasm-storage = { package = "secret-cosmwasm-storage", version = "0.10.0" } schemars = "0.7" -serde = { version = "1", default-features = false, features = [ - "derive" -] } +serde = { version = "1", default-features = false, features = ["derive"] } diff --git a/cosmwasm/contracts/v1/mint/Cargo.toml b/cosmwasm/contracts/v1/mint/Cargo.toml index f0ed7feeb..589ff08a3 100644 --- a/cosmwasm/contracts/v1/mint/Cargo.toml +++ b/cosmwasm/contracts/v1/mint/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "mint" version = "0.9.0-alpha1" -authors = ["Cash Maney "] +authors = ["Cash Maney "] publish = false edition = "2018" description = "Reflect messages to use for test cases - based on cw-mask" @@ -31,7 +31,7 @@ overflow-checks = true default = [] [dependencies] -cosmwasm-std = { package = "secret-cosmwasm-std", version = "0.10.1"} +cosmwasm-std = { package = "secret-cosmwasm-std", version = "0.10.1" } cosmwasm-storage = { package = "secret-cosmwasm-storage", version = "0.10.0" } schemars = "0.7" serde = { version = "=1.0.103", default-features = false, features = [ diff --git a/cosmwasm/enclaves/ffi-types/Cargo.toml b/cosmwasm/enclaves/ffi-types/Cargo.toml index 49694120e..919ab2757 100644 --- a/cosmwasm/enclaves/ffi-types/Cargo.toml +++ b/cosmwasm/enclaves/ffi-types/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "enclave-ffi-types" version = "0.1.0" -authors = ["Reuven Podmazo "] +authors = ["Reuven Podmazo "] edition = "2018" [features] @@ -12,5 +12,5 @@ build_headers = ["cbindgen", "thiserror"] derive_more = "0.99" [build-dependencies] -cbindgen = { version = "0.13", optional = true} -thiserror = { version = "1", optional = true} +cbindgen = { version = "0.13", optional = true } +thiserror = { version = "1", optional = true } diff --git a/cosmwasm/enclaves/shared/contract-engine/Cargo.toml b/cosmwasm/enclaves/shared/contract-engine/Cargo.toml index 03ff030f7..05865287c 100644 --- a/cosmwasm/enclaves/shared/contract-engine/Cargo.toml +++ b/cosmwasm/enclaves/shared/contract-engine/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "enclave_contract_engine" version = "1.6.0" -authors = ["Cashmaney "] +authors = ["Cashmaney "] edition = "2018" [features] @@ -11,7 +11,11 @@ test = [] wasm3 = [] wasmi-engine = ["wasmi", "parity-wasm", "pwasm-utils"] light-client-validation = ["block-verifier"] -random = ["cw_types_generic/random", "cw_types_v1/random", "cw_types_v010/random"] +random = [ + "cw_types_generic/random", + "cw_types_v1/random", + "cw_types_v010/random" +] # This annotation is here to trick the IDE into showing us type information about this crate. # We always compile to the "sgx" target, so this will always be false. @@ -53,8 +57,7 @@ ed25519-zebra = { version = "=2.2.0", default-features = false } rand_core = "0.5.0" rand_chacha = { version = "0.2.1", default-features = false } bincode2 = { git = "https://github.com/scrtlabs/bincode2-sgx", rev = "bdf9f458eaf41778d64cb812ed8fcad64ffd72a9" } - -block-verifier = {path = "../block-verifier", optional = true } +block-verifier = { path = "../block-verifier", optional = true } [dependencies.wasmi] git = "https://github.com/paritytech/wasmi" diff --git a/cosmwasm/enclaves/shared/cosmos-types/Cargo.toml b/cosmwasm/enclaves/shared/cosmos-types/Cargo.toml index 8f6298eae..3951b84f5 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/Cargo.toml +++ b/cosmwasm/enclaves/shared/cosmos-types/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "enclave_cosmos_types" version = "1.6.0" -authors = ["Cashmaney "] +authors = ["Cashmaney "] edition = "2018" [features] diff --git a/cosmwasm/packages/sgx-vm/Cargo.toml b/cosmwasm/packages/sgx-vm/Cargo.toml index aa276df08..bb46f7e57 100644 --- a/cosmwasm/packages/sgx-vm/Cargo.toml +++ b/cosmwasm/packages/sgx-vm/Cargo.toml @@ -3,7 +3,7 @@ name = "cosmwasm-sgx-vm" version = "0.10.0" authors = [ "Ethan Frey ", - "Enigma Team ", + "SCRT Labs ", ] edition = "2018" description = "VM bindings to run cosmwams contracts" @@ -57,7 +57,6 @@ sha2 = "0.10.7" hex = "0.4" memmap = "0.7" parity-wasm = "0.41" - # requirements specific to Secret Network lazy_static = "1.4" enclave-ffi-types = { path = "../../enclaves/ffi-types", features = [ diff --git a/integration-tests/contract-v0.10/Cargo.toml b/integration-tests/contract-v0.10/Cargo.toml index d74eb335b..53a182ee1 100644 --- a/integration-tests/contract-v0.10/Cargo.toml +++ b/integration-tests/contract-v0.10/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "contract-v010" version = "0.0.1" -authors = ["Enigma "] +authors = ["SCRT Labs "] edition = "2018" description = "A test contract intended to use in integration tests for the Secret Netowrk" license = "MIT" diff --git a/seed-service/src/enclaves/ffi-types/Cargo.toml b/seed-service/src/enclaves/ffi-types/Cargo.toml index 92dcd8a8b..7d9de5490 100644 --- a/seed-service/src/enclaves/ffi-types/Cargo.toml +++ b/seed-service/src/enclaves/ffi-types/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "enclave-ffi-types" version = "0.1.0" -authors = ["Reuven Podmazo "] +authors = ["Reuven Podmazo "] edition = "2021" [features] diff --git a/seed-service/src/enclaves/shared/contract-engine/Cargo.toml b/seed-service/src/enclaves/shared/contract-engine/Cargo.toml index 2395c53b9..b82339068 100644 --- a/seed-service/src/enclaves/shared/contract-engine/Cargo.toml +++ b/seed-service/src/enclaves/shared/contract-engine/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "enclave_contract_engine" version = "1.2.4" -authors = ["Cashmaney "] +authors = ["Cashmaney "] edition = "2021" [features] @@ -16,7 +16,6 @@ test = [] # "backtrace" # ] } # sgx_types = { rev = "a37ffb9449ba6d5b6e4a9d586bbab864ae732269", git = "https://github.com/apache/teaclave-sgx-sdk.git" } - [dependencies] enclave-ffi-types = { path = "../../ffi-types" } rustls = "0.20.6" @@ -28,4 +27,4 @@ serde = "1.0.144" serde_json = "1.0.85" log = "0.4.17" hex = "0.4.3" -lazy_static = "1.4.0" \ No newline at end of file +lazy_static = "1.4.0" From 2befcec7566f938c9b1b1261a82c0dd6b8221b81 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 5 Jul 2023 21:50:14 +0300 Subject: [PATCH 067/164] Add support for contracts sending Migrate/Update/Clear messages Tests: - TestContractIsAdminOfAnotherContractMigrate - TestContractIsAdminOfAnotherContractUpdateAdmin - TestContractIsAdminOfAnotherContractClearAdmin - TestContractFailsToMigrateAnotherContractBecauseNotAdmin - TestContractFailsToMigrateAnotherContractBecauseStdError - TestContractFailsToUpdateAdminOfAnotherContractBecauseNotAdmin - TestContractFailsToClearAdminOfAnotherContractBecauseNotAdmin --- client/docs/config.json | 35 +- client/docs/static/openapi/index.html | 111 +- client/docs/static/openapi/openapi.yaml | 4015 ++++++++++++- client/docs/static/swagger/swagger.yaml | 4976 +++++++++++++++-- client/docs/statik/statik.go | 2 +- .../test-compute-contract-v2/Cargo.lock | 8 +- .../test-compute-contract-v2/Cargo.toml | 4 +- .../test-compute-contract-v2/src/contract.rs | 50 + .../test-compute-contract-v2/src/msg.rs | 15 +- .../test-compute-contract/Cargo.lock | 8 +- .../test-compute-contract/Cargo.toml | 4 +- .../test-compute-contract/src/contract.rs | 25 + .../test-compute-contract/src/msg.rs | 15 +- .../enclaves/shared/contract-engine/src/io.rs | 79 +- .../shared/cosmos-proto/src/cosmwasm/msg.rs | 204 +- .../shared/cosmwasm-types/v0.10/src/types.rs | 37 + .../v1.0/src/results/cosmos_msg.rs | 37 + go-cosmwasm/types/v010/msg_v010.go | 39 + go-cosmwasm/types/v1/msg_v1.go | 3 + proto/secret/compute/v1beta1/msg.proto | 15 +- x/compute/handler.go | 3 + x/compute/internal/keeper/handler_plugin.go | 30 +- x/compute/internal/keeper/keeper.go | 39 +- x/compute/internal/keeper/msg_server.go | 6 +- .../keeper/secret_contracts_migrate_test.go | 144 + .../keeper/secret_contracts_utils_test.go | 4 +- .../keeper/testdata/v1-contract-v2.wasm | Bin 1939477 -> 1949403 bytes x/compute/internal/types/msg.pb.go | 404 +- 28 files changed, 9560 insertions(+), 752 deletions(-) diff --git a/client/docs/config.json b/client/docs/config.json index f3a5f5c3f..d3bfa613a 100644 --- a/client/docs/config.json +++ b/client/docs/config.json @@ -3,7 +3,7 @@ "info": { "title": "Secret Network", "description": "A REST interface for queries and transactions", - "version": "v1.8" + "version": "v1.10" }, "apis": [ { @@ -171,6 +171,17 @@ } } }, + { + "url": "../../tmp-swagger-gen/ibc/applications/fee/v1/query.swagger.json", + "operationIds": { + "rename": { + "Params": "../../tmp-swagger-gen/ibc/applications/fee/v1/query.swagger.jsonParams", + "Pool": "../../tmp-swagger-gen/ibc/applications/fee/v1/query.swagger.jsonPool", + "DelegatorValidators": "../../tmp-swagger-gen/ibc/applications/fee/v1/query.swagger.jsonDelegatorValidators", + "UpgradedConsensusState": "../../tmp-swagger-gen/ibc/applications/fee/v1/query.swagger.jsonUpgradedConsensusState" + } + } + }, { "url": "../../tmp-swagger-gen/ibc/applications/interchain_accounts/controller/v1/query.swagger.json", "operationIds": { @@ -193,6 +204,17 @@ } } }, + { + "url": "../../tmp-swagger-gen/ibc/applications/packetforward/v1/query.swagger.json", + "operationIds": { + "rename": { + "Params": "../../tmp-swagger-gen/ibc/applications/packetforward/v1/query.swagger.jsonParams", + "Pool": "../../tmp-swagger-gen/ibc/applications/packetforward/v1/query.swagger.jsonPool", + "DelegatorValidators": "../../tmp-swagger-gen/ibc/applications/packetforward/v1/query.swagger.jsonDelegatorValidators", + "UpgradedConsensusState": "../../tmp-swagger-gen/ibc/applications/packetforward/v1/query.swagger.jsonUpgradedConsensusState" + } + } + }, { "url": "../../tmp-swagger-gen/ibc/applications/transfer/v1/query.swagger.json", "operationIds": { @@ -248,6 +270,17 @@ } } }, + { + "url": "../../tmp-swagger-gen/secret/emergencybutton/v1beta1/query.swagger.json", + "operationIds": { + "rename": { + "Params": "../../tmp-swagger-gen/secret/emergencybutton/v1beta1/query.swagger.jsonParams", + "Pool": "../../tmp-swagger-gen/secret/emergencybutton/v1beta1/query.swagger.jsonPool", + "DelegatorValidators": "../../tmp-swagger-gen/secret/emergencybutton/v1beta1/query.swagger.jsonDelegatorValidators", + "UpgradedConsensusState": "../../tmp-swagger-gen/secret/emergencybutton/v1beta1/query.swagger.jsonUpgradedConsensusState" + } + } + }, { "url": "../../tmp-swagger-gen/secret/intertx/v1beta1/query.swagger.json", "operationIds": { diff --git a/client/docs/static/openapi/index.html b/client/docs/static/openapi/index.html index ea2ac4810..6bbbf8a9f 100644 --- a/client/docs/static/openapi/index.html +++ b/client/docs/static/openapi/index.html @@ -2114,7 +2114,7 @@ stored at the last height of this chain. UpgradedConsensusState RPC not supported with legacy querier This rpc is deprecated now that IBC has its own replacement -(https://github.com/cosmos/ibc-go/blob/2c880a22e9f9cc75f62b527ca94aa75ce1106001/proto/ibc/core/client/v1/query.proto#L54)

  1. getQuery a specific contract code by id
  2. Secret Network (v1.8)

    Download OpenAPI specification:Download

    A REST interface for queries and transactions

    + " fill="currentColor">

    Secret Network (v1.10)

    Download OpenAPI specification:Download

    A REST interface for queries and transactions

    Authentication

    kms

    Security Scheme Type HTTP
    HTTP Authorization Scheme basic

    gRPC Gateway API

    Accounts returns all the existing accounts

    Since: cosmos-sdk 0.43

    query Parameters
    pagination.key
    string <byte>

    key is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key @@ -2792,13 +2793,99 @@ as this is the height under which next consensus state is stored

    Responses

    InterchainAccount returns the interchain account address for a given owner address on a given connection

    path Parameters
    owner
    required
    string
    connection_id
    required
    string

    Responses

    FeeEnabledChannel returns true if the provided port and channel identifiers belong to a fee enabled channel

    path Parameters
    channel_id
    required
    string

    unique channel identifier

    +
    port_id
    required
    string

    unique port identifier

    +

    Responses

    Gets all incentivized packets for a specific channel

    path Parameters
    channel_id
    required
    string
    port_id
    required
    string
    query Parameters
    pagination.key
    string <byte>

    key is a value returned in PageResponse.next_key to begin +querying the next page most efficiently. Only one of offset or key +should be set.

    +
    pagination.offset
    string <uint64>

    offset is a numeric offset that can be used when key is unavailable. +It is less efficient than using key. Only one of offset or key should +be set.

    +
    pagination.limit
    string <uint64>

    limit is the total number of results to be returned in the result page. +If left empty it will default to a value to be set by each app.

    +
    pagination.count_total
    boolean

    count_total is set to true to indicate that the result set should include +a count of the total number of items available for pagination in UIs. +count_total is only respected when offset is used. It is ignored when key +is set.

    +
    pagination.reverse
    boolean

    reverse is set to true if results are to be returned in the descending order.

    +

    Since: cosmos-sdk 0.43

    +
    query_height
    string <uint64>

    Height to query at.

    +

    Responses

    CounterpartyPayee returns the registered counterparty payee for forward relaying

    path Parameters
    channel_id
    required
    string

    unique channel identifier

    +
    relayer
    required
    string

    the relayer address to which the counterparty is registered

    +

    Responses

    Payee returns the registered payee address for a specific channel given the relayer address

    path Parameters
    channel_id
    required
    string

    unique channel identifier

    +
    relayer
    required
    string

    the relayer address to which the distribution address is registered

    +

    Responses

    IncentivizedPacket returns all packet fees for a packet given its identifier

    path Parameters
    packet_id.channel_id
    required
    string

    channel unique identifier

    +
    packet_id.port_id
    required
    string

    channel port identifier

    +
    packet_id.sequence
    required
    string <uint64>

    packet sequence

    +
    query Parameters
    query_height
    string <uint64>

    block height at which to query.

    +

    Responses

    TotalAckFees returns the total acknowledgement fees for a packet given its identifier

    path Parameters
    packet_id.channel_id
    required
    string

    channel unique identifier

    +
    packet_id.port_id
    required
    string

    channel port identifier

    +
    packet_id.sequence
    required
    string <uint64>

    packet sequence

    +

    Responses

    TotalRecvFees returns the total receive fees for a packet given its identifier

    path Parameters
    packet_id.channel_id
    required
    string

    channel unique identifier

    +
    packet_id.port_id
    required
    string

    channel port identifier

    +
    packet_id.sequence
    required
    string <uint64>

    packet sequence

    +

    Responses

    TotalTimeoutFees returns the total timeout fees for a packet given its identifier

    path Parameters
    packet_id.channel_id
    required
    string

    channel unique identifier

    +
    packet_id.port_id
    required
    string

    channel port identifier

    +
    packet_id.sequence
    required
    string <uint64>

    packet sequence

    +

    Responses

    FeeEnabledChannels returns a list of all fee enabled channels

    query Parameters
    pagination.key
    string <byte>

    key is a value returned in PageResponse.next_key to begin +querying the next page most efficiently. Only one of offset or key +should be set.

    +
    pagination.offset
    string <uint64>

    offset is a numeric offset that can be used when key is unavailable. +It is less efficient than using key. Only one of offset or key should +be set.

    +
    pagination.limit
    string <uint64>

    limit is the total number of results to be returned in the result page. +If left empty it will default to a value to be set by each app.

    +
    pagination.count_total
    boolean

    count_total is set to true to indicate that the result set should include +a count of the total number of items available for pagination in UIs. +count_total is only respected when offset is used. It is ignored when key +is set.

    +
    pagination.reverse
    boolean

    reverse is set to true if results are to be returned in the descending order.

    +

    Since: cosmos-sdk 0.43

    +
    query_height
    string <uint64>

    block height at which to query.

    +

    Responses

    IncentivizedPackets returns all incentivized packets and their associated fees

    query Parameters
    pagination.key
    string <byte>

    key is a value returned in PageResponse.next_key to begin +querying the next page most efficiently. Only one of offset or key +should be set.

    +
    pagination.offset
    string <uint64>

    offset is a numeric offset that can be used when key is unavailable. +It is less efficient than using key. Only one of offset or key should +be set.

    +
    pagination.limit
    string <uint64>

    limit is the total number of results to be returned in the result page. +If left empty it will default to a value to be set by each app.

    +
    pagination.count_total
    boolean

    count_total is set to true to indicate that the result set should include +a count of the total number of items available for pagination in UIs. +count_total is only respected when offset is used. It is ignored when key +is set.

    +
    pagination.reverse
    boolean

    reverse is set to true if results are to be returned in the descending order.

    +

    Since: cosmos-sdk 0.43

    +
    query_height
    string <uint64>

    block height at which to query.

    +

    Responses

    InterchainAccount returns the interchain account address for a given owner address on a given connection

    path Parameters
    owner
    required
    string
    connection_id
    required
    string

    Responses

    Params queries all parameters of the ICA controller submodule.

    Responses

    Params queries all parameters of the ICA host submodule.

    Responses

    EscrowAddress returns the escrow address for a particular port and channel id.

    path Parameters
    channel_id
    required
    string

    unique channel identifier

    +

    Params queries all parameters of the router module.

    Responses

    EscrowAddress returns the escrow address for a particular port and channel id.

    path Parameters
    channel_id
    required
    string

    unique channel identifier

    port_id
    required
    string

    unique port identifier

    Responses

    Query contract address by label

    path Parameters
    label
    required
    string

    Responses

    Query code info by id

    path Parameters
    code_id
    required
    string <uint64>

    Responses

    ContractHistory gets the contract code history

    path Parameters
    contract_address
    required
    string

    address is the address of the contract to query

    +

    Responses

    Query code info by id

    path Parameters
    code_id
    required
    string <uint64>

    Responses

    Query contract info by address

    path Parameters
    contract_address
    required
    string

    address is the bech32 human readable address of the contract

    Responses

    Query secret contract

    path Parameters
    contract_address
    required
    string

    address is the bech32 human readable address of the contract

    query Parameters
    query
    string <byte>

    Responses

    QueryInterchainAccountFromAddress returns the interchain account for given owner address on a given connection pair

    query Parameters
    owner
    string
    connection_id
    string

    Responses

    Params defines a gRPC query method that returns the emergencybutton module's +parameters.

    Responses

    QueryInterchainAccountFromAddress returns the interchain account for given owner address on a given connection pair

    path Parameters
    owner
    required
    string
    connection_id
    required
    string

    Responses

    Returns the encrypted seed for a registered node by public key

    path Parameters
    pub_key
    required
    string <byte>

    Responses

    Returns the encrypted seed for a registered node by public key

    path Parameters
    pub_key
    required
    string <byte>

    Responses

    Returns the key used for registration

    Responses

    fpn9PB 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 Date: Wed, 28 Jun 2023 15:24:59 +0300 Subject: [PATCH 051/164] Alias query for `secretcli q wasm smart` --- x/compute/client/cli/query.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/x/compute/client/cli/query.go b/x/compute/client/cli/query.go index fae6b7d50..abda09619 100644 --- a/x/compute/client/cli/query.go +++ b/x/compute/client/cli/query.go @@ -555,10 +555,11 @@ func GetCmdQuery() *cobra.Command { decoder := newArgDecoder(asciiDecodeString) cmd := &cobra.Command{ - Use: "query [bech32_address_or_label] [query]", // TODO add --from wallet - Short: "Calls contract with given address with query data and prints the returned result", - Long: "Calls contract with given address with query data and prints the returned result", - Args: cobra.ExactArgs(2), + Use: "query [bech32_address_or_label] [query]", + Short: "Run a query on a contract", + Long: "Calls contract with given address with query data and prints the returned result", + Aliases: []string{"smart"}, + Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientQueryContext(cmd) if err != nil { From fbccfb7bae34d3e3f53e5132abf12218514f870f Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 28 Jun 2023 15:45:47 +0300 Subject: [PATCH 052/164] Fix updating of contract_key after a migrate & refactor contract_key to be more explicit --- .../src/contract_operations.rs | 4 +- .../src/contract_validation.rs | 4 +- .../shared/cosmwasm-types/generic/src/lib.rs | 100 +++-- .../shared/cosmwasm-types/v0.10/src/types.rs | 30 +- go-cosmwasm/types/env.go | 12 +- proto/secret/compute/v1beta1/types.proto | 10 +- x/compute/internal/keeper/ibc_test.go | 10 +- x/compute/internal/keeper/keeper.go | 42 +- x/compute/internal/keeper/legacy_querier.go | 2 +- x/compute/internal/keeper/relay.go | 2 +- .../keeper/secret_contracts_utils_test.go | 6 +- x/compute/internal/types/types.go | 18 +- x/compute/internal/types/types.pb.go | 408 +++++------------- 13 files changed, 235 insertions(+), 413 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index a5fc4feea..50950401b 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -298,7 +298,7 @@ pub fn migrate( let canonical_sender_address = to_canonical(sender)?; let canonical_admin_address = CanonicalAddr::from_vec(admin.to_vec()); - let og_contract_key = base_env.get_original_contract_key()?; + let og_contract_key = base_env.get_og_contract_key()?; let sender_admin_proof = generate_admin_proof(&canonical_sender_address.0 .0, &og_contract_key); @@ -440,7 +440,7 @@ pub fn update_admin( let canonical_sender_address = to_canonical(sender)?; let canonical_admin_address = CanonicalAddr::from_vec(admin.to_vec()); - let og_contract_key = base_env.get_original_contract_key()?; + let og_contract_key = base_env.get_og_contract_key()?; let sender_admin_proof = generate_admin_proof(&canonical_sender_address.0 .0, &og_contract_key); diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index aa7c73bcc..5d51bdccd 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -209,8 +209,8 @@ pub fn validate_contract_key( if base_env.was_migrated() { println!("Contract was migrated, validating proof"); - let og_contract_key: [u8; CONTRACT_KEY_LENGTH] = base_env.get_original_contract_key()?; - let sent_contract_key_proof = base_env.get_contract_key_proof()?; + let og_contract_key: [u8; CONTRACT_KEY_LENGTH] = base_env.get_og_contract_key()?; + let sent_contract_key_proof = base_env.get_current_contract_key_proof()?; let contract_key_proof = generate_contract_key_proof( &canonical_contract_address.0 .0, diff --git a/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs b/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs index 250a99359..4a12f72df 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs @@ -40,53 +40,93 @@ pub type BaseCanoncalAddr = v010types::CanonicalAddr; pub struct BaseEnv(pub V010Env); impl BaseEnv { - pub fn get_current_contract_key(&self) -> Result<[u8; CONTRACT_KEY_LENGTH], EnclaveError> { - let contract_key = if let Some(contract_key) = &self.0.contract_key { - &contract_key.key.0 + pub fn was_migrated(&self) -> bool { + if let Some(contract_key) = &self.0.contract_key { + contract_key.current_contract_key.is_some() + && contract_key.current_contract_key_proof.is_some() + && contract_key.og_contract_key.is_some() // this one might be unnecessary } else { - warn!("Contract execute with empty contract key"); - return Err(EnclaveError::FailedContractAuthentication); - }; - - if contract_key.len() != CONTRACT_KEY_LENGTH { - warn!("Contract execute with empty contract key"); - return Err(EnclaveError::FailedContractAuthentication); + false } + } - let mut key_as_bytes = [0u8; CONTRACT_KEY_LENGTH]; - key_as_bytes.copy_from_slice(contract_key); + pub fn get_og_contract_key(&self) -> Result<[u8; CONTRACT_KEY_LENGTH], EnclaveError> { + if let Some(contract_key) = &self.0.contract_key { + let og_contract_key = if let Some(og_contract_key) = &contract_key.og_contract_key { + &og_contract_key.0 + } else { + warn!("Tried to get an empty og_contract_key"); + return Err(EnclaveError::FailedContractAuthentication); + }; - Ok(key_as_bytes) - } + if og_contract_key.len() != CONTRACT_KEY_LENGTH { + warn!("Tried to get an empty og_contract_key"); + return Err(EnclaveError::FailedContractAuthentication); + } - pub fn was_migrated(&self) -> bool { - if let Some(key) = &self.0.contract_key { - key.original.is_some() + let mut as_bytes: [u8; CONTRACT_KEY_LENGTH] = [0u8; CONTRACT_KEY_LENGTH]; + as_bytes.copy_from_slice(og_contract_key); + + Ok(as_bytes) } else { - false + warn!("Tried to get og_contract_key from an empty contract_key"); + Err(EnclaveError::FailedContractAuthentication) } } - pub fn get_original_contract_key(&self) -> Result<[u8; CONTRACT_KEY_LENGTH], EnclaveError> { - if let Some(key) = &self.0.contract_key { - if self.was_migrated() { - Ok(key.original.clone().unwrap().get_key()) - } else { - self.get_current_contract_key() + pub fn get_current_contract_key(&self) -> Result<[u8; CONTRACT_KEY_LENGTH], EnclaveError> { + if let Some(contract_key) = &self.0.contract_key { + let current_contract_key = + if let Some(current_contract_key) = &contract_key.current_contract_key { + ¤t_contract_key.0 + } else { + if let Some(og_contract_key) = &contract_key.og_contract_key { + &og_contract_key.0 + } else { + warn!("Tried to get an empty current_contract_key & og_contract_key"); + return Err(EnclaveError::FailedContractAuthentication); + } + }; + + if current_contract_key.len() != CONTRACT_KEY_LENGTH { + warn!("Tried to get an empty current_contract_key"); + return Err(EnclaveError::FailedContractAuthentication); } + + let mut as_bytes: [u8; CONTRACT_KEY_LENGTH] = [0u8; CONTRACT_KEY_LENGTH]; + as_bytes.copy_from_slice(current_contract_key); + + Ok(as_bytes) } else { + warn!("Tried to get current_contract_key from an empty contract_key"); Err(EnclaveError::FailedContractAuthentication) } } - pub fn get_contract_key_proof(&self) -> Result<[u8; CONTRACT_KEY_PROOF_LENGTH], EnclaveError> { - if let Some(key) = &self.0.contract_key { - if self.was_migrated() { - Ok(key.original.clone().unwrap().get_proof()) + pub fn get_current_contract_key_proof( + &self, + ) -> Result<[u8; CONTRACT_KEY_PROOF_LENGTH], EnclaveError> { + if let Some(contract_key) = &self.0.contract_key { + let current_contract_key_proof = if let Some(current_contract_key_proof) = + &contract_key.current_contract_key_proof + { + ¤t_contract_key_proof.0 } else { - Err(EnclaveError::FailedContractAuthentication) + warn!("Tried to get an empty current_contract_key_proof"); + return Err(EnclaveError::FailedContractAuthentication); + }; + + if current_contract_key_proof.len() != CONTRACT_KEY_PROOF_LENGTH { + warn!("Tried to get an empty current_contract_key_proof"); + return Err(EnclaveError::FailedContractAuthentication); } + + let mut as_bytes: [u8; CONTRACT_KEY_PROOF_LENGTH] = [0u8; CONTRACT_KEY_PROOF_LENGTH]; + as_bytes.copy_from_slice(current_contract_key_proof); + + Ok(as_bytes) } else { + warn!("Tried to get current_contract_key_proof from an empty contract_key"); Err(EnclaveError::FailedContractAuthentication) } } @@ -136,7 +176,7 @@ impl BaseEnv { contract: v010types::ContractInfo { address: self.0.contract.address, }, - // to maintain compatability with v010 we just return none here - no contract would care + // to maintain compatability with v010 we just return none here - no contract should care // about this anyway contract_key: None, contract_code_hash: self.0.contract_code_hash, diff --git a/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/types.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/types.rs index bfe7bccc2..5ed69b18c 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/types.rs @@ -105,30 +105,12 @@ impl fmt::Display for CanonicalAddr { #[derive(Serialize, Deserialize, Clone, Default, Debug, PartialEq)] pub struct ContractKey { - pub key: Binary, - pub original: Option, -} - -#[derive(Serialize, Deserialize, Clone, Default, Debug, PartialEq)] -pub struct ContractKeyWithProof { - pub key: Binary, - pub proof: Binary, -} - -impl ContractKeyWithProof { - pub fn get_key(&self) -> [u8; CONTRACT_KEY_LENGTH] { - let mut output = [0u8; CONTRACT_KEY_LENGTH]; - output.copy_from_slice(&self.key.0); - - output - } - - pub fn get_proof(&self) -> [u8; CONTRACT_KEY_PROOF_LENGTH] { - let mut output = [0u8; CONTRACT_KEY_PROOF_LENGTH]; - output.copy_from_slice(&self.proof.0); - - output - } + #[serde(default)] + pub og_contract_key: Option, + #[serde(default)] + pub current_contract_key: Option, + #[serde(default)] + pub current_contract_key_proof: Option, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] diff --git a/go-cosmwasm/types/env.go b/go-cosmwasm/types/env.go index 68205b225..e3e107adb 100644 --- a/go-cosmwasm/types/env.go +++ b/go-cosmwasm/types/env.go @@ -11,19 +11,15 @@ type Env struct { Block BlockInfo `json:"block"` Message MessageInfo `json:"message"` Contract ContractInfo `json:"contract"` - Key *ContractKey `json:"contract_key,omitempty"` + Key ContractKey `json:"contract_key"` QueryDepth uint32 `json:"query_depth"` Transaction *TransactionInfo `json:"transaction,omitempty"` } type ContractKey struct { - Key []byte `json:"key"` - Original *ContractKeyWithProof `json:"original,omitempty"` -} - -type ContractKeyWithProof struct { - Key []byte `json:"key,omitempty"` - Proof []byte `json:"proof,omitempty"` + OgContractKey []byte `protobuf:"bytes,1,opt,name=og_contract_key,json=ogContractKey,proto3" json:"og_contract_key,omitempty"` + CurrentContractKey []byte `protobuf:"bytes,2,opt,name=current_contract_key,json=currentContractKey,proto3" json:"current_contract_key,omitempty"` + CurrentContractKeyProof []byte `protobuf:"bytes,3,opt,name=current_contract_key_proof,json=currentContractKeyProof,proto3" json:"current_contract_key_proof,omitempty"` } type TransactionInfo struct { diff --git a/proto/secret/compute/v1beta1/types.proto b/proto/secret/compute/v1beta1/types.proto index 07036b8fa..5caf7f2ff 100644 --- a/proto/secret/compute/v1beta1/types.proto +++ b/proto/secret/compute/v1beta1/types.proto @@ -35,13 +35,9 @@ message ContractCustomInfo { } message ContractKey { - bytes key = 1; - ContractKeyWithProof original = 2; -} - -message ContractKeyWithProof { - bytes key = 1; - bytes proof = 2; + bytes og_contract_key = 1; + bytes current_contract_key = 2; + bytes current_contract_key_proof = 3; } // ContractInfo stores a WASM contract instance diff --git a/x/compute/internal/keeper/ibc_test.go b/x/compute/internal/keeper/ibc_test.go index 07398befb..0d9133844 100644 --- a/x/compute/internal/keeper/ibc_test.go +++ b/x/compute/internal/keeper/ibc_test.go @@ -94,7 +94,7 @@ func ibcChannelConnectHelper( return ctx, nil, cosmwasm.StdError{GenericErr: &cosmwasm.GenericErr{Msg: err.Error()}} } - // wasmEvents comes from all the callbacks as well + // wasmEvents come from all the callbacks as well wasmEvents := tryDecryptWasmEvents(ctx, []byte{}, true) return ctx, wasmEvents, cosmwasm.StdError{} @@ -250,7 +250,7 @@ func ibcChannelCloseHelper( return ctx, nil, cosmwasm.StdError{GenericErr: &cosmwasm.GenericErr{Msg: err.Error()}} } - // wasmEvents comes from all the callbacks as well + // wasmEvents come from all the callbacks as well wasmEvents := tryDecryptWasmEvents(ctx, []byte{}, true) return ctx, wasmEvents, cosmwasm.StdError{} @@ -348,7 +348,7 @@ func ibcPacketReceiveHelper( require.NotZero(t, gasMeter.GetWasmCounter(), err) - // wasmEvents comes from all the callbacks as well + // wasmEvents come from all the callbacks as well wasmEvents := tryDecryptWasmEvents(ctx, nonce, !shouldEncryptMsg) if err != nil { @@ -424,7 +424,7 @@ func ibcPacketAckHelper( return ctx, nil, cosmwasm.StdError{GenericErr: &cosmwasm.GenericErr{Msg: err.Error()}} } - // wasmEvents comes from all the callbacks as well + // wasmEvents come from all the callbacks as well wasmEvents := tryDecryptWasmEvents(ctx, []byte{}, true) return ctx, wasmEvents, cosmwasm.StdError{} @@ -483,7 +483,7 @@ func ibcPacketTimeoutHelper( return ctx, nil, cosmwasm.StdError{GenericErr: &cosmwasm.GenericErr{Msg: err.Error()}} } - // wasmEvents comes from all the callbacks as well + // wasmEvents come from all the callbacks as well wasmEvents := tryDecryptWasmEvents(ctx, []byte{}, true) return ctx, wasmEvents, cosmwasm.StdError{} diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index c870dc8f7..2a0daecaa 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -467,7 +467,17 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.A random := k.GetRandomSeed(ctx, ctx.BlockHeight()) // prepare env for contract instantiate call - env := types.NewEnv(ctx, creator, deposit, contractAddress, nil, random) + env := types.NewEnv(ctx, + creator, + deposit, + contractAddress, + types.ContractKey{ + OgContractKey: nil, + CurrentContractKey: nil, + CurrentContractKeyProof: nil, + }, + random, + ) // create prefixed data store // 0x03 | contractAddress (sdk.AccAddress) @@ -483,7 +493,7 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.A // instantiate wasm contract gas := gasForContract(ctx) - response, key, adminProof, gasUsed, initError := k.wasmer.Instantiate(codeInfo.CodeHash, env, initMsg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, verificationInfo, admin) + response, ogContractKey, adminProof, gasUsed, initError := k.wasmer.Instantiate(codeInfo.CodeHash, env, initMsg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, verificationInfo, admin) consumeGas(ctx, gasUsed) if initError != nil { @@ -515,7 +525,9 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.A k.setContractInfo(ctx, contractAddress, &contractInfo) k.SetContractKey(ctx, contractAddress, &types.ContractKey{ - Key: key, + OgContractKey: ogContractKey, + CurrentContractKey: nil, + CurrentContractKeyProof: nil, }) store.Set(types.GetContractLabelPrefix(label), contractAddress) @@ -563,7 +575,9 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.A // persist instance k.setContractInfo(ctx, contractAddress, &contractInfo) k.SetContractKey(ctx, contractAddress, &types.ContractKey{ - Key: key, + OgContractKey: ogContractKey, + CurrentContractKey: nil, + CurrentContractKeyProof: nil, }) store.Set(types.GetContractLabelPrefix(label), contractAddress) @@ -625,7 +639,7 @@ func (k Keeper) Execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller return nil, err } - env := types.NewEnv(ctx, caller, coins, contractAddress, &contractKey, random) + env := types.NewEnv(ctx, caller, coins, contractAddress, contractKey, random) // prepare querier querier := QueryHandler{ @@ -727,7 +741,7 @@ func (k Keeper) querySmartImpl(ctx sdk.Context, contractAddress sdk.AccAddress, sdk.AccAddress{}, /* empty because it's unused in queries */ sdk.NewCoins(), /* empty because it's unused in queries */ contractAddress, - &contractKey, + contractKey, []byte{0}, /* empty because it's unused in queries */ ) params.QueryDepth = queryDepth @@ -1153,7 +1167,7 @@ func (k Keeper) reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply v1w random := k.GetRandomSeed(ctx, ctx.BlockHeight()) - env := types.NewEnv(ctx, contractAddress, sdk.Coins{}, contractAddress, &contractKey, random) + env := types.NewEnv(ctx, contractAddress, sdk.Coins{}, contractAddress, contractKey, random) // prepare querier querier := QueryHandler{ @@ -1224,7 +1238,7 @@ func (k Keeper) UpdateContractAdmin(ctx sdk.Context, contractAddress, caller, ne return err } - env := types.NewEnv(ctx, caller, sdk.Coins{}, contractAddress, &contractKey, nil) + env := types.NewEnv(ctx, caller, sdk.Coins{}, contractAddress, contractKey, nil) currentAdminProof := k.GetContractInfo(ctx, contractAddress).AdminProof currentAdmin := k.GetContractInfo(ctx, contractAddress).Admin @@ -1312,7 +1326,7 @@ func (k Keeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller random := k.GetRandomSeed(ctx, ctx.BlockHeight()) - env := types.NewEnv(ctx, caller, sdk.Coins{}, contractAddress, &contractKey, random) + env := types.NewEnv(ctx, caller, sdk.Coins{}, contractAddress, contractKey, random) adminProof := k.GetContractInfo(ctx, contractAddress).AdminProof admin := k.GetContractInfo(ctx, contractAddress).Admin @@ -1332,7 +1346,7 @@ func (k Keeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller // instantiate wasm contract gas := gasForContract(ctx) - response, newContractKey, proof, gasUsed, migrateErr := k.wasmer.Migrate(newCodeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, gasMeter(ctx), gas, verificationInfo, adminAddr, adminProof) + response, newContractKey, newContractKeyProof, gasUsed, migrateErr := k.wasmer.Migrate(newCodeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, gasMeter(ctx), gas, verificationInfo, adminAddr, adminProof) consumeGas(ctx, gasUsed) if migrateErr != nil { @@ -1351,11 +1365,9 @@ func (k Keeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller // update contract key with new one k.SetContractKey(ctx, contractAddress, &types.ContractKey{ - Key: newContractKey, - Original: &types.ContractKeyWithProof{ - Key: contractKey.Key, - Proof: proof, - }, + OgContractKey: contractKey.OgContractKey, + CurrentContractKey: newContractKey, + CurrentContractKeyProof: newContractKeyProof, }) // delete old secondary index entry diff --git a/x/compute/internal/keeper/legacy_querier.go b/x/compute/internal/keeper/legacy_querier.go index 09de22fda..89ccb3c68 100644 --- a/x/compute/internal/keeper/legacy_querier.go +++ b/x/compute/internal/keeper/legacy_querier.go @@ -140,5 +140,5 @@ func queryContractKey(ctx sdk.Context, address sdk.AccAddress, keeper Keeper) ([ return nil, nil } - return res.Key, nil + return res.CurrentContractKey, nil } diff --git a/x/compute/internal/keeper/relay.go b/x/compute/internal/keeper/relay.go index dfb1bbc92..b0a7ed6e9 100644 --- a/x/compute/internal/keeper/relay.go +++ b/x/compute/internal/keeper/relay.go @@ -45,7 +45,7 @@ func (k Keeper) ibcContractCall(ctx sdk.Context, sdk.AccAddress{}, /* there's no MessageInfo for IBC contract calls */ sdk.NewCoins(), /* there's no MessageInfo for IBC contract calls */ contractAddress, - &contractKey, + contractKey, random, ) diff --git a/x/compute/internal/keeper/secret_contracts_utils_test.go b/x/compute/internal/keeper/secret_contracts_utils_test.go index 4565b54d2..afc852f6f 100644 --- a/x/compute/internal/keeper/secret_contracts_utils_test.go +++ b/x/compute/internal/keeper/secret_contracts_utils_test.go @@ -572,7 +572,7 @@ func execTxBuilderImpl( return results, &errResult } - // wasmEvents comes from all the callbacks as well + // wasmEvents come from all the callbacks as well wasmEvents := tryDecryptWasmEvents(ctx, nonce, shouldSkipAttributes...) // Data is the output of only the first call @@ -643,7 +643,7 @@ func initHelperImpl( return nil, ctx, nil, nil, extractInnerError(t, err, nonce, isErrorEncrypted, isV1Contract) } - // wasmEvents comes from all the callbacks as well + // wasmEvents come from all the callbacks as well wasmEvents := tryDecryptWasmEvents(ctx, nonce, shouldSkipAttributes...) // TODO check if we can extract the messages from ctx @@ -765,7 +765,7 @@ func migrateHelper( return result, &errResult } - // wasmEvents comes from all the callbacks as well + // wasmEvents come from all the callbacks as well wasmEvents := tryDecryptWasmEvents(ctx, nonce, shouldSkipAttributes...) // Data is the output of only the first call diff --git a/x/compute/internal/types/types.go b/x/compute/internal/types/types.go index 30f4df47e..bdf61bdd6 100644 --- a/x/compute/internal/types/types.go +++ b/x/compute/internal/types/types.go @@ -120,7 +120,7 @@ func (a *AbsoluteTxPosition) Bytes() []byte { } // NewEnv initializes the environment for a contract instance -func NewEnv(ctx sdk.Context, creator sdk.AccAddress, deposit sdk.Coins, contractAddr sdk.AccAddress, contractKey *ContractKey, random []byte) wasmTypes.Env { +func NewEnv(ctx sdk.Context, creator sdk.AccAddress, deposit sdk.Coins, contractAddr sdk.AccAddress, contractKey ContractKey, random []byte) wasmTypes.Env { // safety checks before casting below if ctx.BlockHeight() < 0 { panic("Block height must never be negative") @@ -146,18 +146,10 @@ func NewEnv(ctx sdk.Context, creator sdk.AccAddress, deposit sdk.Coins, contract QueryDepth: 1, } - if contractKey != nil { - env.Key = &wasmTypes.ContractKey{ - Key: contractKey.Key, - Original: nil, - } - - if contractKey.Original != nil { - env.Key.Original = &wasmTypes.ContractKeyWithProof{ - Proof: contractKey.Original.Proof, - Key: contractKey.Original.Key, - } - } + env.Key = wasmTypes.ContractKey{ + OgContractKey: contractKey.OgContractKey, + CurrentContractKey: contractKey.CurrentContractKey, + CurrentContractKeyProof: contractKey.CurrentContractKeyProof, } if txCounter, ok := TXCounter(ctx); ok { diff --git a/x/compute/internal/types/types.pb.go b/x/compute/internal/types/types.pb.go index 16464e4e3..48134e816 100644 --- a/x/compute/internal/types/types.pb.go +++ b/x/compute/internal/types/types.pb.go @@ -206,8 +206,9 @@ func (m *ContractCustomInfo) XXX_DiscardUnknown() { var xxx_messageInfo_ContractCustomInfo proto.InternalMessageInfo type ContractKey struct { - Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - Original *ContractKeyWithProof `protobuf:"bytes,2,opt,name=original,proto3" json:"original,omitempty"` + OgContractKey []byte `protobuf:"bytes,1,opt,name=og_contract_key,json=ogContractKey,proto3" json:"og_contract_key,omitempty"` + CurrentContractKey []byte `protobuf:"bytes,2,opt,name=current_contract_key,json=currentContractKey,proto3" json:"current_contract_key,omitempty"` + CurrentContractKeyProof []byte `protobuf:"bytes,3,opt,name=current_contract_key_proof,json=currentContractKeyProof,proto3" json:"current_contract_key_proof,omitempty"` } func (m *ContractKey) Reset() { *m = ContractKey{} } @@ -243,44 +244,6 @@ func (m *ContractKey) XXX_DiscardUnknown() { var xxx_messageInfo_ContractKey proto.InternalMessageInfo -type ContractKeyWithProof struct { - Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - Proof []byte `protobuf:"bytes,2,opt,name=proof,proto3" json:"proof,omitempty"` -} - -func (m *ContractKeyWithProof) Reset() { *m = ContractKeyWithProof{} } -func (m *ContractKeyWithProof) String() string { return proto.CompactTextString(m) } -func (*ContractKeyWithProof) ProtoMessage() {} -func (*ContractKeyWithProof) Descriptor() ([]byte, []int) { - return fileDescriptor_8ba7f40a6d1951b3, []int{4} -} -func (m *ContractKeyWithProof) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ContractKeyWithProof) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ContractKeyWithProof.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *ContractKeyWithProof) XXX_Merge(src proto.Message) { - xxx_messageInfo_ContractKeyWithProof.Merge(m, src) -} -func (m *ContractKeyWithProof) XXX_Size() int { - return m.Size() -} -func (m *ContractKeyWithProof) XXX_DiscardUnknown() { - xxx_messageInfo_ContractKeyWithProof.DiscardUnknown(m) -} - -var xxx_messageInfo_ContractKeyWithProof proto.InternalMessageInfo - // ContractInfo stores a WASM contract instance type ContractInfo struct { // CodeID is the reference to the stored Wasm code @@ -302,7 +265,7 @@ func (m *ContractInfo) Reset() { *m = ContractInfo{} } func (m *ContractInfo) String() string { return proto.CompactTextString(m) } func (*ContractInfo) ProtoMessage() {} func (*ContractInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_8ba7f40a6d1951b3, []int{5} + return fileDescriptor_8ba7f40a6d1951b3, []int{4} } func (m *ContractInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -343,7 +306,7 @@ func (m *AbsoluteTxPosition) Reset() { *m = AbsoluteTxPosition{} } func (m *AbsoluteTxPosition) String() string { return proto.CompactTextString(m) } func (*AbsoluteTxPosition) ProtoMessage() {} func (*AbsoluteTxPosition) Descriptor() ([]byte, []int) { - return fileDescriptor_8ba7f40a6d1951b3, []int{6} + return fileDescriptor_8ba7f40a6d1951b3, []int{5} } func (m *AbsoluteTxPosition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -384,7 +347,7 @@ func (m *Model) Reset() { *m = Model{} } func (m *Model) String() string { return proto.CompactTextString(m) } func (*Model) ProtoMessage() {} func (*Model) Descriptor() ([]byte, []int) { - return fileDescriptor_8ba7f40a6d1951b3, []int{7} + return fileDescriptor_8ba7f40a6d1951b3, []int{6} } func (m *Model) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -427,7 +390,7 @@ func (m *ContractCodeHistoryEntry) Reset() { *m = ContractCodeHistoryEnt func (m *ContractCodeHistoryEntry) String() string { return proto.CompactTextString(m) } func (*ContractCodeHistoryEntry) ProtoMessage() {} func (*ContractCodeHistoryEntry) Descriptor() ([]byte, []int) { - return fileDescriptor_8ba7f40a6d1951b3, []int{8} + return fileDescriptor_8ba7f40a6d1951b3, []int{7} } func (m *ContractCodeHistoryEntry) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -463,7 +426,6 @@ func init() { proto.RegisterType((*CodeInfo)(nil), "secret.compute.v1beta1.CodeInfo") proto.RegisterType((*ContractCustomInfo)(nil), "secret.compute.v1beta1.ContractCustomInfo") proto.RegisterType((*ContractKey)(nil), "secret.compute.v1beta1.ContractKey") - proto.RegisterType((*ContractKeyWithProof)(nil), "secret.compute.v1beta1.ContractKeyWithProof") proto.RegisterType((*ContractInfo)(nil), "secret.compute.v1beta1.ContractInfo") proto.RegisterType((*AbsoluteTxPosition)(nil), "secret.compute.v1beta1.AbsoluteTxPosition") proto.RegisterType((*Model)(nil), "secret.compute.v1beta1.Model") @@ -475,73 +437,73 @@ func init() { } var fileDescriptor_8ba7f40a6d1951b3 = []byte{ - // 1043 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0x4b, 0x6f, 0x23, 0x45, - 0x10, 0xf6, 0xc4, 0x8e, 0x1f, 0x6d, 0xb3, 0x58, 0x4d, 0x58, 0xbc, 0x46, 0xb2, 0xcd, 0x80, 0x60, - 0xd9, 0x6c, 0x6c, 0xb2, 0x70, 0x58, 0xe5, 0x80, 0xe4, 0xc7, 0x6c, 0x32, 0x1b, 0x62, 0x5b, 0x6d, - 0x27, 0xab, 0xf0, 0xd0, 0x68, 0x1e, 0x1d, 0xbb, 0x95, 0xf1, 0xb4, 0xd5, 0xdd, 0x0e, 0xf6, 0x3f, - 0x40, 0x3e, 0x71, 0xe4, 0x62, 0x09, 0x09, 0xb4, 0xda, 0x3f, 0xc0, 0x1f, 0xe0, 0xb4, 0xc7, 0x3d, - 0x72, 0xb2, 0xc0, 0xf9, 0x01, 0x48, 0x1c, 0xf7, 0x84, 0xa6, 0xc7, 0x2f, 0x41, 0xa2, 0x04, 0x89, - 0xd3, 0x54, 0x75, 0x57, 0x7d, 0x55, 0xfd, 0xf5, 0x57, 0x3d, 0x40, 0xe5, 0xd8, 0x66, 0x58, 0x94, - 0x6c, 0xda, 0xeb, 0x0f, 0x04, 0x2e, 0x5d, 0xec, 0x5a, 0x58, 0x98, 0xbb, 0x25, 0x31, 0xea, 0x63, - 0x5e, 0xec, 0x33, 0x2a, 0x28, 0xbc, 0x1b, 0xc4, 0x14, 0xe7, 0x31, 0xc5, 0x79, 0x4c, 0x76, 0xab, - 0x43, 0x3b, 0x54, 0x86, 0x94, 0x7c, 0x2b, 0x88, 0x56, 0x6d, 0xf0, 0x66, 0xd9, 0xb6, 0x31, 0xe7, - 0xed, 0x51, 0x1f, 0x37, 0x4d, 0x66, 0xf6, 0xe0, 0x53, 0xb0, 0x79, 0x61, 0xba, 0x03, 0x9c, 0x51, - 0x0a, 0xca, 0xfd, 0x3b, 0x8f, 0xd4, 0xe2, 0xd5, 0x80, 0xc5, 0x55, 0x5e, 0x25, 0xfd, 0xd7, 0x34, - 0x9f, 0x1a, 0x99, 0x3d, 0x77, 0x4f, 0x95, 0xa9, 0x2a, 0x0a, 0x20, 0xf6, 0x22, 0x3f, 0xfc, 0x98, - 0x57, 0xd4, 0xe7, 0x0a, 0x88, 0x57, 0xa9, 0x83, 0x75, 0xef, 0x8c, 0xc2, 0x77, 0x41, 0xc2, 0xa6, - 0x0e, 0x36, 0xba, 0x26, 0xef, 0xca, 0x12, 0x29, 0x14, 0xf7, 0x17, 0x0e, 0x4c, 0xde, 0x85, 0x87, - 0x20, 0x66, 0x33, 0x6c, 0x0a, 0xca, 0x32, 0x1b, 0xfe, 0x56, 0x65, 0xf7, 0xf5, 0x34, 0xbf, 0xd3, - 0x21, 0xa2, 0x3b, 0xb0, 0xfc, 0x06, 0x4a, 0x36, 0xe5, 0x3d, 0xca, 0xe7, 0x9f, 0x1d, 0xee, 0x9c, - 0xcf, 0xcf, 0x5e, 0xb6, 0xed, 0xb2, 0xe3, 0x30, 0xcc, 0x39, 0x5a, 0x20, 0xc0, 0xbb, 0x20, 0xca, - 0xe9, 0x80, 0xd9, 0x38, 0x13, 0x2e, 0x28, 0xf7, 0x13, 0x68, 0xee, 0xc1, 0x0c, 0x88, 0x59, 0x03, - 0xe2, 0x3a, 0x98, 0x65, 0x22, 0x72, 0x63, 0xe1, 0xaa, 0x5f, 0x01, 0x58, 0xa5, 0x9e, 0x60, 0xa6, - 0x2d, 0xaa, 0x03, 0x2e, 0x68, 0x4f, 0x76, 0x5c, 0x02, 0x49, 0xec, 0xd9, 0xae, 0x79, 0x81, 0x8d, - 0x73, 0x3c, 0x0a, 0x7a, 0xae, 0xdc, 0x99, 0x4d, 0xf3, 0x40, 0x0b, 0x96, 0x0f, 0xf1, 0x08, 0x01, - 0xbc, 0xb4, 0xe1, 0x16, 0xd8, 0x74, 0x4d, 0x0b, 0xbb, 0xf2, 0x0c, 0x09, 0x14, 0x38, 0x2a, 0x01, - 0xc9, 0x05, 0xb8, 0x1f, 0x94, 0x06, 0xe1, 0x25, 0x1a, 0xf2, 0x4d, 0x78, 0x00, 0xe2, 0x94, 0x91, - 0x0e, 0xf1, 0xcc, 0x20, 0x33, 0xf9, 0xe8, 0xe1, 0x75, 0xdc, 0xaf, 0x01, 0x3d, 0x23, 0xa2, 0xdb, - 0x64, 0x94, 0x9e, 0xa1, 0x65, 0xb6, 0xfa, 0x39, 0xd8, 0xba, 0x2a, 0xe2, 0x8a, 0x9a, 0x5b, 0x60, - 0xb3, 0xef, 0x6f, 0x05, 0x74, 0xa3, 0xc0, 0x51, 0x7f, 0xdd, 0x00, 0xa9, 0x05, 0x80, 0xa4, 0xe0, - 0x7d, 0x10, 0x93, 0x97, 0x46, 0x1c, 0x99, 0x1c, 0xa9, 0x80, 0xd9, 0x34, 0x1f, 0x95, 0x77, 0x5a, - 0x43, 0x51, 0x7f, 0x4b, 0x77, 0xfe, 0xdf, 0xcb, 0x5b, 0x72, 0x18, 0x59, 0xe3, 0x10, 0xd6, 0xe6, - 0x25, 0xb0, 0x93, 0xd9, 0x94, 0x0c, 0x3d, 0xb8, 0x56, 0x9d, 0x16, 0xa7, 0xee, 0x40, 0xe0, 0xf6, - 0xb0, 0x49, 0x39, 0x11, 0x84, 0x7a, 0x68, 0x91, 0x0a, 0x77, 0x40, 0x92, 0x58, 0xb6, 0xd1, 0xa7, - 0x4c, 0xf8, 0x27, 0x8a, 0xfa, 0x15, 0x2a, 0x6f, 0xcc, 0xa6, 0xf9, 0x84, 0x5e, 0xa9, 0x36, 0x29, - 0x13, 0x7a, 0x0d, 0x25, 0x88, 0x65, 0x4b, 0xd3, 0xf1, 0x5b, 0x31, 0x9d, 0x1e, 0xf1, 0x32, 0xb1, - 0xa0, 0x15, 0xe9, 0xc0, 0x3c, 0x48, 0x4a, 0xc3, 0x08, 0xf8, 0x8b, 0x4b, 0xfe, 0x80, 0x5c, 0x92, - 0x64, 0xab, 0x08, 0xc0, 0x7f, 0x37, 0x01, 0xdf, 0x03, 0x29, 0xcb, 0xa5, 0xf6, 0xb9, 0xd1, 0xc5, - 0xa4, 0xd3, 0x15, 0x92, 0xce, 0x30, 0x4a, 0xca, 0xb5, 0x03, 0xb9, 0x04, 0xef, 0x81, 0xb8, 0x18, - 0x1a, 0xc4, 0x73, 0xf0, 0x50, 0x12, 0x19, 0x41, 0x31, 0x31, 0xd4, 0x7d, 0x57, 0x25, 0x60, 0xf3, - 0x88, 0x3a, 0xd8, 0x85, 0x4f, 0x41, 0xf8, 0x70, 0xa9, 0xc5, 0xc7, 0xaf, 0xa7, 0xf9, 0xcf, 0xd6, - 0x78, 0x16, 0xd8, 0x73, 0x30, 0xeb, 0x11, 0x4f, 0xac, 0x9b, 0x2e, 0xb1, 0x78, 0xc9, 0x1a, 0x09, - 0xcc, 0x8b, 0x07, 0x78, 0x58, 0xf1, 0x0d, 0x14, 0x9e, 0xcb, 0xf5, 0x44, 0x0e, 0xfc, 0x5c, 0x03, - 0xd2, 0x51, 0xff, 0x54, 0x40, 0x66, 0x39, 0x0c, 0xfe, 0x7c, 0x12, 0x2e, 0x28, 0x1b, 0x69, 0x9e, - 0x60, 0x23, 0x78, 0x02, 0x12, 0xb4, 0x8f, 0x99, 0xe9, 0x1f, 0x69, 0xfe, 0x4e, 0x3c, 0xbe, 0x49, - 0xab, 0x6b, 0x20, 0x8d, 0x45, 0xae, 0xff, 0x7a, 0xa0, 0x15, 0xd4, 0xba, 0xce, 0x36, 0xae, 0xd5, - 0x59, 0x0d, 0xc4, 0x06, 0x7d, 0x47, 0x8a, 0x20, 0xfc, 0xdf, 0x45, 0x30, 0x4f, 0xf5, 0x67, 0xa1, - 0xc7, 0x3b, 0x52, 0x5e, 0x29, 0xe4, 0x9b, 0x0f, 0x7e, 0x51, 0x00, 0x58, 0x3d, 0x6a, 0xf0, 0x43, - 0x90, 0x38, 0xae, 0xd7, 0xb4, 0x27, 0x7a, 0x5d, 0xab, 0xa5, 0x43, 0xd9, 0x77, 0xc6, 0x93, 0xc2, - 0x5b, 0xab, 0xed, 0x63, 0xcf, 0xc1, 0x67, 0xc4, 0xc3, 0x0e, 0x2c, 0x80, 0x68, 0xbd, 0x51, 0x69, - 0xd4, 0x4e, 0xd3, 0x4a, 0x76, 0x6b, 0x3c, 0x29, 0xa4, 0x57, 0x41, 0x75, 0x6a, 0x51, 0x67, 0x04, - 0xb7, 0x41, 0xaa, 0x51, 0xff, 0xe2, 0xd4, 0x28, 0xd7, 0x6a, 0x48, 0x6b, 0xb5, 0xd2, 0x1b, 0xd9, - 0x7b, 0xe3, 0x49, 0xe1, 0xed, 0x55, 0x5c, 0xc3, 0x73, 0x47, 0xf3, 0x09, 0xf0, 0xcb, 0x6a, 0x27, - 0x1a, 0x3a, 0x95, 0x88, 0xe1, 0x7f, 0x96, 0xd5, 0x2e, 0x30, 0x1b, 0xf9, 0xa0, 0xd9, 0xf8, 0x77, - 0x3f, 0xe5, 0x42, 0x2f, 0x7e, 0xce, 0x85, 0x1e, 0x3c, 0x0f, 0x83, 0xc2, 0x4d, 0x24, 0x43, 0x0c, - 0x3e, 0xa9, 0x36, 0xea, 0x6d, 0x54, 0xae, 0xb6, 0x8d, 0x6a, 0xa3, 0xa6, 0x19, 0x07, 0x7a, 0xab, - 0xdd, 0x40, 0xa7, 0x46, 0xa3, 0xa9, 0xa1, 0x72, 0x5b, 0x6f, 0xd4, 0x8d, 0xf6, 0x69, 0x53, 0x33, - 0x8e, 0xeb, 0xad, 0xa6, 0x56, 0xd5, 0x9f, 0xe8, 0xf2, 0xd0, 0xa5, 0xf1, 0xa4, 0xb0, 0x7d, 0x13, - 0xf6, 0xb1, 0xc7, 0xfb, 0xd8, 0x26, 0x67, 0x04, 0x3b, 0xf0, 0x19, 0xf8, 0xf8, 0x56, 0x65, 0xf4, - 0xba, 0xde, 0x4e, 0x2b, 0xd9, 0xfb, 0xe3, 0x49, 0xe1, 0x83, 0x9b, 0xf0, 0x75, 0x8f, 0x08, 0xf8, - 0x0d, 0x78, 0x78, 0x2b, 0xe0, 0x23, 0x7d, 0x1f, 0x95, 0xdb, 0x5a, 0x7a, 0x23, 0xbb, 0x3d, 0x9e, - 0x14, 0x3e, 0xba, 0x09, 0xfb, 0x88, 0x74, 0x98, 0x29, 0xf0, 0xad, 0xe1, 0xf7, 0xb5, 0xba, 0xd6, - 0xd2, 0x5b, 0xe9, 0xf0, 0xed, 0xe0, 0xf7, 0xb1, 0x87, 0x39, 0xe1, 0xd9, 0x88, 0x7f, 0x59, 0x95, - 0xaf, 0x5f, 0xfe, 0x91, 0x0b, 0xbd, 0x98, 0xe5, 0x94, 0x97, 0xb3, 0x9c, 0xf2, 0x6a, 0x96, 0x53, - 0x7e, 0x9f, 0xe5, 0x94, 0xef, 0x2f, 0x73, 0xa1, 0x57, 0x97, 0xb9, 0xd0, 0x6f, 0x97, 0xb9, 0xd0, - 0x97, 0x7b, 0x6b, 0x53, 0xcc, 0x6d, 0x26, 0x5c, 0xd3, 0xe2, 0xa5, 0x96, 0x14, 0x77, 0x1d, 0x8b, - 0x6f, 0x29, 0x3b, 0x2f, 0x0d, 0x97, 0x7f, 0x7f, 0xe2, 0x09, 0xcc, 0x3c, 0xd3, 0x0d, 0x5e, 0x51, - 0x2b, 0x2a, 0xff, 0xe8, 0x9f, 0xfe, 0x1d, 0x00, 0x00, 0xff, 0xff, 0xf8, 0x2c, 0xb1, 0x67, 0x25, - 0x08, 0x00, 0x00, + // 1045 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0x4d, 0x6f, 0x1a, 0x47, + 0x18, 0x66, 0x0d, 0x06, 0x33, 0x90, 0x04, 0x4d, 0xdd, 0x84, 0x50, 0x09, 0x28, 0xad, 0x52, 0x37, + 0xae, 0x21, 0x4e, 0x7b, 0x88, 0xdc, 0x13, 0x1f, 0x1b, 0x7b, 0xe3, 0x7a, 0x41, 0x03, 0x76, 0xe5, + 0x7e, 0x68, 0xb5, 0x1f, 0x63, 0x58, 0x79, 0xd9, 0x41, 0x33, 0x83, 0xcb, 0xfe, 0x83, 0x8a, 0x53, + 0x8f, 0xbd, 0x20, 0x55, 0x6a, 0x14, 0xe5, 0x0f, 0xf4, 0x0f, 0xf4, 0x94, 0x63, 0x8e, 0x3d, 0xa1, + 0x16, 0xff, 0x80, 0x4a, 0x3d, 0xe6, 0x54, 0xed, 0xec, 0x62, 0x68, 0x63, 0xcb, 0xae, 0xd4, 0xd3, + 0xbe, 0x9f, 0xcf, 0xfb, 0xbe, 0xcf, 0xbc, 0x33, 0x0b, 0x4a, 0x0c, 0x9b, 0x14, 0xf3, 0x8a, 0x49, + 0xfa, 0x83, 0x21, 0xc7, 0x95, 0xb3, 0x6d, 0x03, 0x73, 0x7d, 0xbb, 0xc2, 0xbd, 0x01, 0x66, 0xe5, + 0x01, 0x25, 0x9c, 0xc0, 0xbb, 0x41, 0x4c, 0x39, 0x8c, 0x29, 0x87, 0x31, 0xb9, 0xf5, 0x2e, 0xe9, + 0x12, 0x11, 0x52, 0xf1, 0xa5, 0x20, 0xba, 0x64, 0x82, 0x3b, 0x55, 0xd3, 0xc4, 0x8c, 0x75, 0xbc, + 0x01, 0x6e, 0xe9, 0x54, 0xef, 0xc3, 0x67, 0x60, 0xf5, 0x4c, 0x77, 0x86, 0x38, 0x2b, 0x15, 0xa5, + 0x8d, 0xdb, 0x8f, 0x4b, 0xe5, 0xcb, 0x01, 0xcb, 0x8b, 0xbc, 0x5a, 0xe6, 0xaf, 0x69, 0x21, 0xed, + 0xe9, 0x7d, 0x67, 0xa7, 0x24, 0x52, 0x4b, 0x28, 0x80, 0xd8, 0x89, 0xfd, 0xf8, 0x53, 0x41, 0x2a, + 0xbd, 0x90, 0xc0, 0x5a, 0x9d, 0x58, 0x58, 0x71, 0x4f, 0x08, 0x7c, 0x0f, 0x24, 0x4d, 0x62, 0x61, + 0xad, 0xa7, 0xb3, 0x9e, 0x28, 0x91, 0x46, 0x6b, 0xbe, 0x61, 0x4f, 0x67, 0x3d, 0xb8, 0x0f, 0x12, + 0x26, 0xc5, 0x3a, 0x27, 0x34, 0xbb, 0xe2, 0xbb, 0x6a, 0xdb, 0x6f, 0xa6, 0x85, 0xad, 0xae, 0xcd, + 0x7b, 0x43, 0xc3, 0x6f, 0xa0, 0x62, 0x12, 0xd6, 0x27, 0x2c, 0xfc, 0x6c, 0x31, 0xeb, 0x34, 0x9c, + 0xbd, 0x6a, 0x9a, 0x55, 0xcb, 0xa2, 0x98, 0x31, 0x34, 0x47, 0x80, 0x77, 0x41, 0x9c, 0x91, 0x21, + 0x35, 0x71, 0x36, 0x5a, 0x94, 0x36, 0x92, 0x28, 0xd4, 0x60, 0x16, 0x24, 0x8c, 0xa1, 0xed, 0x58, + 0x98, 0x66, 0x63, 0xc2, 0x31, 0x57, 0x4b, 0x5f, 0x03, 0x58, 0x27, 0x2e, 0xa7, 0xba, 0xc9, 0xeb, + 0x43, 0xc6, 0x49, 0x5f, 0x74, 0x5c, 0x01, 0x29, 0xec, 0x9a, 0x8e, 0x7e, 0x86, 0xb5, 0x53, 0xec, + 0x05, 0x3d, 0xd7, 0x6e, 0xcf, 0xa6, 0x05, 0x20, 0x07, 0xe6, 0x7d, 0xec, 0x21, 0x80, 0x2f, 0x64, + 0xb8, 0x0e, 0x56, 0x1d, 0xdd, 0xc0, 0x8e, 0x98, 0x21, 0x89, 0x02, 0xa5, 0xf4, 0x5c, 0x02, 0xa9, + 0x39, 0xba, 0x1f, 0xf5, 0x00, 0xdc, 0x21, 0x5d, 0xcd, 0x0c, 0x2d, 0x0b, 0x68, 0x74, 0x8b, 0x74, + 0x97, 0xe3, 0x1e, 0x81, 0x75, 0x73, 0x48, 0x29, 0x76, 0xf9, 0x3f, 0x83, 0x05, 0x41, 0x08, 0x86, + 0xbe, 0xe5, 0x8c, 0xcf, 0x41, 0xee, 0xb2, 0x0c, 0x6d, 0x40, 0x09, 0x39, 0x11, 0x64, 0xa4, 0xd1, + 0xbd, 0xb7, 0xf3, 0x5a, 0xbe, 0xbb, 0xf4, 0xeb, 0x0a, 0x48, 0xcf, 0x8d, 0x62, 0xfc, 0x0f, 0x40, + 0x42, 0x1c, 0x98, 0x6d, 0x89, 0xfe, 0x62, 0x35, 0x30, 0x9b, 0x16, 0xe2, 0xe2, 0x3c, 0x1b, 0x28, + 0xee, 0xbb, 0x14, 0xeb, 0xff, 0x3d, 0xb8, 0x0b, 0xfe, 0x62, 0x4b, 0xfc, 0xc1, 0x46, 0x58, 0x02, + 0x5b, 0xd9, 0xd5, 0xa2, 0xb4, 0x91, 0x7a, 0xfc, 0xf0, 0xca, 0xcd, 0x34, 0x18, 0x71, 0x86, 0x1c, + 0x77, 0x46, 0x2d, 0xc2, 0x6c, 0x6e, 0x13, 0x17, 0xcd, 0x53, 0xe1, 0x16, 0x48, 0xd9, 0x86, 0xa9, + 0x0d, 0x08, 0xe5, 0xfe, 0x44, 0x71, 0xbf, 0x42, 0xed, 0xd6, 0x6c, 0x5a, 0x48, 0x2a, 0xb5, 0x7a, + 0x8b, 0x50, 0xae, 0x34, 0x50, 0xd2, 0x36, 0x4c, 0x21, 0x5a, 0x7e, 0x2b, 0xba, 0xd5, 0xb7, 0xdd, + 0x6c, 0x22, 0x68, 0x45, 0x28, 0xb0, 0x00, 0x52, 0x42, 0x08, 0x19, 0x5d, 0x13, 0x8c, 0x02, 0x61, + 0x0a, 0x48, 0x44, 0x00, 0xbe, 0xdd, 0x04, 0x7c, 0x1f, 0xa4, 0x0d, 0x87, 0x98, 0xa7, 0x5a, 0x0f, + 0xdb, 0xdd, 0x1e, 0x17, 0x74, 0x46, 0x51, 0x4a, 0xd8, 0xf6, 0x84, 0x09, 0xde, 0x07, 0x6b, 0x7c, + 0xa4, 0xd9, 0xae, 0x85, 0x47, 0x82, 0xc8, 0x18, 0x4a, 0xf0, 0x91, 0xe2, 0xab, 0x25, 0x1b, 0xac, + 0x1e, 0x10, 0x0b, 0x3b, 0xf0, 0x19, 0x88, 0xee, 0x5f, 0xec, 0xe1, 0x93, 0x37, 0xd3, 0xc2, 0x67, + 0x4b, 0x3c, 0x73, 0xec, 0x5a, 0x98, 0xf6, 0x6d, 0x97, 0x2f, 0x8b, 0x8e, 0x6d, 0xb0, 0x8a, 0xe1, + 0x71, 0xcc, 0xca, 0x7b, 0x78, 0x54, 0xf3, 0x05, 0x14, 0x0d, 0x57, 0xf5, 0x48, 0x5c, 0xf6, 0x60, + 0x9b, 0x02, 0xa5, 0xf4, 0xa7, 0x04, 0xb2, 0x17, 0x17, 0xc1, 0xbf, 0x9b, 0x36, 0xe3, 0x84, 0x7a, + 0xb2, 0xcb, 0xa9, 0x07, 0x8f, 0x40, 0x92, 0x0c, 0x30, 0xd5, 0xfd, 0x91, 0xc2, 0x37, 0xe2, 0xc9, + 0x55, 0x27, 0x71, 0x09, 0x48, 0x73, 0x9e, 0xeb, 0xbf, 0x1c, 0x68, 0x01, 0xb5, 0xbc, 0x67, 0x2b, + 0x57, 0xee, 0x59, 0x03, 0x24, 0x86, 0x03, 0x4b, 0x2c, 0x41, 0xf4, 0xbf, 0x2f, 0x41, 0x98, 0x0a, + 0x33, 0x20, 0xda, 0x67, 0x5d, 0xb1, 0x5e, 0x69, 0xe4, 0x8b, 0x0f, 0x7f, 0x91, 0x00, 0x58, 0x3c, + 0x68, 0xf0, 0x01, 0x48, 0x1e, 0xaa, 0x0d, 0xf9, 0xa9, 0xa2, 0xca, 0x8d, 0x4c, 0x24, 0x77, 0x6f, + 0x3c, 0x29, 0xbe, 0xb3, 0x70, 0x1f, 0xba, 0x16, 0x3e, 0xb1, 0x5d, 0x6c, 0xc1, 0x22, 0x88, 0xab, + 0xcd, 0x5a, 0xb3, 0x71, 0x9c, 0x91, 0x72, 0xeb, 0xe3, 0x49, 0x31, 0xb3, 0x08, 0x52, 0x89, 0x41, + 0x2c, 0x0f, 0x6e, 0x82, 0x74, 0x53, 0xfd, 0xe2, 0x58, 0xab, 0x36, 0x1a, 0x48, 0x6e, 0xb7, 0x33, + 0x2b, 0xb9, 0xfb, 0xe3, 0x49, 0xf1, 0xdd, 0x45, 0x5c, 0xd3, 0x75, 0xbc, 0xf0, 0x06, 0xf8, 0x65, + 0xe5, 0x23, 0x19, 0x1d, 0x0b, 0xc4, 0xe8, 0xbf, 0xcb, 0xca, 0x67, 0x98, 0x7a, 0x3e, 0x68, 0x6e, + 0xed, 0xfb, 0x9f, 0xf3, 0x91, 0x97, 0xcf, 0xf3, 0x91, 0x87, 0x2f, 0xa2, 0xa0, 0x78, 0x1d, 0xc9, + 0x10, 0x83, 0x47, 0xf5, 0xa6, 0xda, 0x41, 0xd5, 0x7a, 0x47, 0xab, 0x37, 0x1b, 0xb2, 0xb6, 0xa7, + 0xb4, 0x3b, 0x4d, 0x74, 0xac, 0x35, 0x5b, 0x32, 0xaa, 0x76, 0x94, 0xa6, 0xaa, 0x75, 0x8e, 0x5b, + 0xb2, 0x76, 0xa8, 0xb6, 0x5b, 0x72, 0x5d, 0x79, 0xaa, 0x88, 0xa1, 0x2b, 0xe3, 0x49, 0x71, 0xf3, + 0x3a, 0xec, 0x43, 0x97, 0x0d, 0xb0, 0x69, 0x9f, 0xd8, 0xd8, 0x82, 0x5f, 0x82, 0x8f, 0x6f, 0x54, + 0x46, 0x51, 0x95, 0x4e, 0x46, 0xca, 0x6d, 0x8c, 0x27, 0xc5, 0x0f, 0xaf, 0xc3, 0x57, 0x5c, 0x9b, + 0xc3, 0x6f, 0xc1, 0x27, 0x37, 0x02, 0x3e, 0x50, 0x76, 0x51, 0xb5, 0x23, 0x67, 0x56, 0x72, 0x9b, + 0xe3, 0x49, 0xf1, 0xa3, 0xeb, 0xb0, 0x0f, 0xec, 0x2e, 0xd5, 0x39, 0xbe, 0x31, 0xfc, 0xae, 0xac, + 0xca, 0x6d, 0xa5, 0x9d, 0x89, 0xde, 0x0c, 0x7e, 0x17, 0xbb, 0x98, 0xd9, 0x2c, 0x17, 0xf3, 0x0f, + 0xab, 0xf6, 0xcd, 0xab, 0x3f, 0xf2, 0x91, 0x97, 0xb3, 0xbc, 0xf4, 0x6a, 0x96, 0x97, 0x5e, 0xcf, + 0xf2, 0xd2, 0xef, 0xb3, 0xbc, 0xf4, 0xc3, 0x79, 0x3e, 0xf2, 0xfa, 0x3c, 0x1f, 0xf9, 0xed, 0x3c, + 0x1f, 0xf9, 0x6a, 0x67, 0xe9, 0x16, 0x33, 0x93, 0x72, 0x47, 0x37, 0x58, 0xa5, 0x2d, 0x96, 0x5b, + 0xc5, 0xfc, 0x3b, 0x42, 0x4f, 0x2b, 0xa3, 0x8b, 0x3f, 0xbf, 0xed, 0x72, 0x4c, 0x5d, 0xdd, 0x09, + 0x5e, 0x51, 0x23, 0x2e, 0xfe, 0xe6, 0x9f, 0xfe, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x1b, 0xb7, 0x51, + 0xb6, 0x21, 0x08, 0x00, 0x00, } func (this *AccessTypeParam) Equal(that interface{}) bool { @@ -647,37 +609,13 @@ func (this *ContractKey) Equal(that interface{}) bool { } else if this == nil { return false } - if !bytes.Equal(this.Key, that1.Key) { - return false - } - if !this.Original.Equal(that1.Original) { - return false - } - return true -} -func (this *ContractKeyWithProof) Equal(that interface{}) bool { - if that == nil { - return this == nil - } - - that1, ok := that.(*ContractKeyWithProof) - if !ok { - that2, ok := that.(ContractKeyWithProof) - if ok { - that1 = &that2 - } else { - return false - } - } - if that1 == nil { - return this == nil - } else if this == nil { + if !bytes.Equal(this.OgContractKey, that1.OgContractKey) { return false } - if !bytes.Equal(this.Key, that1.Key) { + if !bytes.Equal(this.CurrentContractKey, that1.CurrentContractKey) { return false } - if !bytes.Equal(this.Proof, that1.Proof) { + if !bytes.Equal(this.CurrentContractKeyProof, that1.CurrentContractKeyProof) { return false } return true @@ -947,59 +885,24 @@ func (m *ContractKey) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.Original != nil { - { - size, err := m.Original.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTypes(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - if len(m.Key) > 0 { - i -= len(m.Key) - copy(dAtA[i:], m.Key) - i = encodeVarintTypes(dAtA, i, uint64(len(m.Key))) + if len(m.CurrentContractKeyProof) > 0 { + i -= len(m.CurrentContractKeyProof) + copy(dAtA[i:], m.CurrentContractKeyProof) + i = encodeVarintTypes(dAtA, i, uint64(len(m.CurrentContractKeyProof))) i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *ContractKeyWithProof) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err + dAtA[i] = 0x1a } - return dAtA[:n], nil -} - -func (m *ContractKeyWithProof) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ContractKeyWithProof) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Proof) > 0 { - i -= len(m.Proof) - copy(dAtA[i:], m.Proof) - i = encodeVarintTypes(dAtA, i, uint64(len(m.Proof))) + if len(m.CurrentContractKey) > 0 { + i -= len(m.CurrentContractKey) + copy(dAtA[i:], m.CurrentContractKey) + i = encodeVarintTypes(dAtA, i, uint64(len(m.CurrentContractKey))) i-- dAtA[i] = 0x12 } - if len(m.Key) > 0 { - i -= len(m.Key) - copy(dAtA[i:], m.Key) - i = encodeVarintTypes(dAtA, i, uint64(len(m.Key))) + if len(m.OgContractKey) > 0 { + i -= len(m.OgContractKey) + copy(dAtA[i:], m.OgContractKey) + i = encodeVarintTypes(dAtA, i, uint64(len(m.OgContractKey))) i-- dAtA[i] = 0xa } @@ -1274,28 +1177,15 @@ func (m *ContractKey) Size() (n int) { } var l int _ = l - l = len(m.Key) + l = len(m.OgContractKey) if l > 0 { n += 1 + l + sovTypes(uint64(l)) } - if m.Original != nil { - l = m.Original.Size() - n += 1 + l + sovTypes(uint64(l)) - } - return n -} - -func (m *ContractKeyWithProof) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Key) + l = len(m.CurrentContractKey) if l > 0 { n += 1 + l + sovTypes(uint64(l)) } - l = len(m.Proof) + l = len(m.CurrentContractKeyProof) if l > 0 { n += 1 + l + sovTypes(uint64(l)) } @@ -1797,7 +1687,7 @@ func (m *ContractKey) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field OgContractKey", wireType) } var byteLen int for shift := uint(0); ; shift += 7 { @@ -1824,100 +1714,14 @@ func (m *ContractKey) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Key = append(m.Key[:0], dAtA[iNdEx:postIndex]...) - if m.Key == nil { - m.Key = []byte{} + m.OgContractKey = append(m.OgContractKey[:0], dAtA[iNdEx:postIndex]...) + if m.OgContractKey == nil { + m.OgContractKey = []byte{} } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Original", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Original == nil { - m.Original = &ContractKeyWithProof{} - } - if err := m.Original.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipTypes(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthTypes - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ContractKeyWithProof) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ContractKeyWithProof: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ContractKeyWithProof: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CurrentContractKey", wireType) } var byteLen int for shift := uint(0); ; shift += 7 { @@ -1944,14 +1748,14 @@ func (m *ContractKeyWithProof) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Key = append(m.Key[:0], dAtA[iNdEx:postIndex]...) - if m.Key == nil { - m.Key = []byte{} + m.CurrentContractKey = append(m.CurrentContractKey[:0], dAtA[iNdEx:postIndex]...) + if m.CurrentContractKey == nil { + m.CurrentContractKey = []byte{} } iNdEx = postIndex - case 2: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Proof", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CurrentContractKeyProof", wireType) } var byteLen int for shift := uint(0); ; shift += 7 { @@ -1978,9 +1782,9 @@ func (m *ContractKeyWithProof) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Proof = append(m.Proof[:0], dAtA[iNdEx:postIndex]...) - if m.Proof == nil { - m.Proof = []byte{} + m.CurrentContractKeyProof = append(m.CurrentContractKeyProof[:0], dAtA[iNdEx:postIndex]...) + if m.CurrentContractKeyProof == nil { + m.CurrentContractKeyProof = []byte{} } iNdEx = postIndex default: From 0a371f7d00264bd6cd6c6aeaa99c718884cdb8ef Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Thu, 29 Jun 2023 13:21:19 +0300 Subject: [PATCH 053/164] clippy --- .../enclaves/shared/cosmwasm-types/generic/src/lib.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs b/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs index 4a12f72df..3df8569c0 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs @@ -79,13 +79,11 @@ impl BaseEnv { let current_contract_key = if let Some(current_contract_key) = &contract_key.current_contract_key { ¤t_contract_key.0 + } else if let Some(og_contract_key) = &contract_key.og_contract_key { + &og_contract_key.0 } else { - if let Some(og_contract_key) = &contract_key.og_contract_key { - &og_contract_key.0 - } else { - warn!("Tried to get an empty current_contract_key & og_contract_key"); - return Err(EnclaveError::FailedContractAuthentication); - } + warn!("Tried to get an empty current_contract_key & og_contract_key"); + return Err(EnclaveError::FailedContractAuthentication); }; if current_contract_key.len() != CONTRACT_KEY_LENGTH { From a4577965b974d046856923b63d61c77409c31017 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Fri, 30 Jun 2023 15:26:07 +0300 Subject: [PATCH 054/164] Copy execute behavior to migrate in test contract --- .../test-compute-contract-v2/Cargo.lock | 8 +- .../test-compute-contract-v2/Cargo.toml | 4 +- .../test-compute-contract-v2/src/contract.rs | 985 +++++++++++++++++- .../test-compute-contract-v2/src/msg.rs | 9 +- .../test-compute-contract/Cargo.lock | 86 +- .../test-compute-contract/Cargo.toml | 5 +- .../keeper/testdata/v1-contract-v2.wasm | Bin 1892280 -> 1939477 bytes 7 files changed, 1033 insertions(+), 64 deletions(-) diff --git a/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Cargo.lock b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Cargo.lock index a5ae4f7f4..3a8275523 100644 --- a/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Cargo.lock +++ b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Cargo.lock @@ -86,7 +86,7 @@ checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" [[package]] name = "cosmwasm-derive" version = "1.1.10" -source = "git+https://github.com/scrtlabs/cosmwasm?rev=6c639b5#6c639b5a85ef66f87d72284dc68ae051eab09007" +source = "git+https://github.com/scrtlabs/cosmwasm?rev=c91d5f2#c91d5f2e8bf0d69cb40ca95e0ce9946fb084b628" dependencies = [ "syn 1.0.109", ] @@ -462,7 +462,7 @@ dependencies = [ [[package]] name = "secret-cosmwasm-crypto" version = "1.1.10" -source = "git+https://github.com/scrtlabs/cosmwasm?rev=6c639b5#6c639b5a85ef66f87d72284dc68ae051eab09007" +source = "git+https://github.com/scrtlabs/cosmwasm?rev=c91d5f2#c91d5f2e8bf0d69cb40ca95e0ce9946fb084b628" dependencies = [ "digest 0.10.7", "ed25519-zebra", @@ -474,7 +474,7 @@ dependencies = [ [[package]] name = "secret-cosmwasm-std" version = "1.1.10" -source = "git+https://github.com/scrtlabs/cosmwasm?rev=6c639b5#6c639b5a85ef66f87d72284dc68ae051eab09007" +source = "git+https://github.com/scrtlabs/cosmwasm?rev=c91d5f2#c91d5f2e8bf0d69cb40ca95e0ce9946fb084b628" dependencies = [ "base64", "cosmwasm-derive", @@ -492,7 +492,7 @@ dependencies = [ [[package]] name = "secret-cosmwasm-storage" version = "1.1.10" -source = "git+https://github.com/scrtlabs/cosmwasm?rev=6c639b5#6c639b5a85ef66f87d72284dc68ae051eab09007" +source = "git+https://github.com/scrtlabs/cosmwasm?rev=c91d5f2#c91d5f2e8bf0d69cb40ca95e0ce9946fb084b628" dependencies = [ "secret-cosmwasm-std", "serde", diff --git a/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Cargo.toml b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Cargo.toml index 866de30ac..7a48b1462 100644 --- a/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Cargo.toml +++ b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/Cargo.toml @@ -31,10 +31,10 @@ backtraces = ["cosmwasm-std/backtraces"] with_floats = [] [dependencies] -cosmwasm-std = { git = "https://github.com/scrtlabs/cosmwasm", rev = "6c639b5", package = "secret-cosmwasm-std", features = [ +cosmwasm-std = { git = "https://github.com/scrtlabs/cosmwasm", rev = "c91d5f2", package = "secret-cosmwasm-std", features = [ "random" ] } -cosmwasm-storage = { git = "https://github.com/scrtlabs/cosmwasm", rev = "6c639b5", package = "secret-cosmwasm-storage" } +cosmwasm-storage = { git = "https://github.com/scrtlabs/cosmwasm", rev = "c91d5f2", package = "secret-cosmwasm-storage" } schemars = "0.8.1" serde = { version = "1.0.114", default-features = false, features = [ "derive", diff --git a/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/contract.rs b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/contract.rs index c30cefb06..17b6a2ccf 100644 --- a/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/contract.rs +++ b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/contract.rs @@ -11,8 +11,7 @@ use cosmwasm_storage::PrefixedStorage; use secp256k1::Secp256k1; use crate::msg::{ - ExecuteMsg, ExternalMessages, IBCLifecycleComplete, InstantiateMsg, MigrateMsg, QueryMsg, - QueryRes, + ExecuteMsg, ExternalMessages, IBCLifecycleComplete, InstantiateMsg, QueryMsg, QueryRes, }; use crate::state::{count, count_read, expiration, expiration_read, PREFIX_TEST, TEST_KEY}; @@ -362,6 +361,8 @@ pub fn wasm_msg(ty: String) -> StdResult { #[entry_point] pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> StdResult { match msg { + ExecuteMsg::Nop {} => Ok(Response::default()), + ExecuteMsg::StdError {} => Err(StdError::generic_err("this is an std error")), ExecuteMsg::IncrementTimes { times } => { let mut res = Response::default(); for _ in 0..times { @@ -2701,9 +2702,983 @@ fn remove_from_storage_in_query(storage: &dyn Storage) -> StdResult { const REALLY_LONG: &[u8] = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; #[entry_point] -pub fn migrate(_deps: DepsMut, _env: Env, msg: MigrateMsg) -> StdResult { +pub fn migrate(deps: DepsMut, env: Env, msg: ExecuteMsg) -> StdResult { match msg { - MigrateMsg::Nop {} => Ok(Response::default()), - MigrateMsg::StdError {} => Err(StdError::generic_err("this is an std error")), + ExecuteMsg::Nop {} => Ok(Response::default()), + ExecuteMsg::StdError {} => Err(StdError::generic_err("this is an std error")), + ExecuteMsg::IncrementTimes { times } => { + let mut res = Response::default(); + for _ in 0..times { + res = res.add_message(CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: env.contract.code_hash.clone(), + contract_addr: env.contract.address.clone().into_string(), + msg: Binary::from("{\"increment\":{\"addition\":1}}".as_bytes().to_vec()), + funds: vec![], + })); + } + Ok(res) + } + ExecuteMsg::LastMsgMarkerNop {} => { + // also tests using finalize like this + Ok(Response::new().add_message(CosmosMsg::FinalizeTx(Empty {}))) + } + ExecuteMsg::LastMsgMarker {} => { + let increment_msg = SubMsg { + id: 0, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: env.contract.code_hash, + contract_addr: env.contract.address.into_string(), + msg: Binary::from("{\"increment\":{\"addition\":1}}".as_bytes().to_vec()), + funds: vec![], + }) + .into(), + reply_on: ReplyOn::Never, + gas_limit: None, + }; + + let bank_msg = SubMsg { + id: 0, + msg: CosmosMsg::Bank(BankMsg::Send { + to_address: "".to_string(), + amount: coins(1u128, "ust"), + }) + .into(), + reply_on: ReplyOn::Never, + gas_limit: None, + }; + Ok(Response::new() + .add_submessages(vec![ + increment_msg.clone(), + increment_msg.clone(), + increment_msg.clone(), + increment_msg.clone(), + ]) + // also tests using finalize like this + .add_message(CosmosMsg::finalize_tx()) + .add_submessages(vec![increment_msg.clone(), bank_msg.clone()])) + } + ExecuteMsg::WasmMsg { ty } => wasm_msg(ty), + ExecuteMsg::Increment { addition } => increment(env, deps, addition), + ExecuteMsg::SendFundsWithErrorWithReply {} => Ok(Response::new() + .add_submessage(SubMsg { + id: 8000, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: env.contract.code_hash, + contract_addr: env.contract.address.into_string(), + msg: Binary::from(r#"{"add_more_attributes":{}}"#.as_bytes().to_vec()), + funds: coins(100, "lior"), + }) + .into(), + reply_on: ReplyOn::Always, + gas_limit: None, + }) + .add_attribute("attr1", "🦄") + .add_attribute("attr2", "🌈")), + ExecuteMsg::SendFundsWithReply {} => Ok(Response::new() + .add_submessage(SubMsg { + id: 8001, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: env.contract.code_hash, + contract_addr: env.contract.address.into_string(), + msg: Binary::from(r#"{"add_more_attributes":{}}"#.as_bytes().to_vec()), + funds: coins(100, "denom"), + }) + .into(), + reply_on: ReplyOn::Always, + gas_limit: None, + }) + .add_attribute("attr1", "🦄") + .add_attribute("attr2", "🌈")), + ExecuteMsg::AddAttributes {} => Ok(Response::new() + .add_attribute("attr1", "🦄") + .add_attribute("attr2", "🌈")), + ExecuteMsg::AddAttributesWithSubmessage { id } => Ok(Response::new() + .add_submessage(SubMsg { + id, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: env.contract.code_hash, + contract_addr: env.contract.address.into_string(), + msg: Binary::from(r#"{"add_more_attributes":{}}"#.as_bytes().to_vec()), + funds: vec![], + }) + .into(), + reply_on: match id { + 0 => ReplyOn::Never, + _ => ReplyOn::Always, + }, + gas_limit: None, + }) + .add_attribute("attr1", "🦄") + .add_attribute("attr2", "🌈")), + ExecuteMsg::AddMoreAttributes {} => Ok(Response::new() + .add_attribute("attr3", "🍉") + .add_attribute("attr4", "🥝")), + ExecuteMsg::AddPlaintextAttributes {} => Ok(Response::new() + .add_attribute_plaintext("attr1", "🦄") + .add_attribute_plaintext("attr2", "🌈")), + ExecuteMsg::AddPlaintextAttributesWithSubmessage { id } => Ok(Response::new() + .add_submessage(SubMsg { + id, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: env.contract.code_hash, + contract_addr: env.contract.address.into_string(), + msg: Binary::from( + r#"{"add_more_plaintext_attributes":{}}"#.as_bytes().to_vec(), + ), + funds: vec![], + }) + .into(), + reply_on: match id { + 0 => ReplyOn::Never, + _ => ReplyOn::Always, + }, + gas_limit: None, + }) + .add_attribute_plaintext("attr1", "🦄") + .add_attribute_plaintext("attr2", "🌈")), + ExecuteMsg::AddMorePlaintextAttributes {} => Ok(Response::new() + .add_attribute_plaintext("attr3", "🍉") + .add_attribute_plaintext("attr4", "🥝")), + + ExecuteMsg::AddEvents {} => Ok(Response::new() + .add_event( + Event::new("cyber1".to_string()) + .add_attribute("attr1", "🦄") + .add_attribute("attr2", "🌈"), + ) + .add_event( + Event::new("cyber2".to_string()) + .add_attribute("attr3", "🐙") + .add_attribute("attr4", "🦄"), + )), + ExecuteMsg::AddEventsWithSubmessage { id } => Ok(Response::new() + .add_submessage(SubMsg { + id, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: env.contract.code_hash, + contract_addr: env.contract.address.into_string(), + msg: Binary::from(r#"{"add_more_events":{}}"#.as_bytes().to_vec()), + funds: vec![], + }) + .into(), + reply_on: match id { + 0 => ReplyOn::Never, + _ => ReplyOn::Always, + }, + gas_limit: None, + }) + .add_event( + Event::new("cyber1".to_string()) + .add_attribute("attr1", "🦄") + .add_attribute("attr2", "🌈"), + ) + .add_event( + Event::new("cyber2".to_string()) + .add_attribute("attr3", "🐙") + .add_attribute("attr4", "🦄"), + )), + ExecuteMsg::AddMoreEvents {} => Ok(Response::new() + .add_event( + Event::new("cyber3".to_string()) + .add_attribute("attr1", "🤯") + .add_attribute("attr2", "🤟"), + ) + .add_event( + Event::new("cyber4".to_string()) + .add_attribute("attr3", "😅") + .add_attribute("attr4", "🦄"), + )), + + ExecuteMsg::AddMixedAttributesAndEvents {} => Ok(Response::new() + .add_event( + Event::new("cyber1".to_string()) + .add_attribute_plaintext("attr1", "🦄") + .add_attribute_plaintext("attr2", "🌈"), + ) + .add_attribute_plaintext("attr3", "🐙") + .add_attribute_plaintext("attr4", "🦄")), + ExecuteMsg::AddMixedAttributesAndEventsWithSubmessage { id } => Ok(Response::new() + .add_submessage(SubMsg { + id, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: env.contract.code_hash, + contract_addr: env.contract.address.into_string(), + msg: Binary::from( + r#"{"add_more_mixed_attributes_and_events":{}}"#.as_bytes().to_vec(), + ), + funds: vec![], + }) + .into(), + reply_on: match id { + 0 => ReplyOn::Never, + _ => ReplyOn::Always, + }, + gas_limit: None, + }) + .add_event( + Event::new("cyber1".to_string()) + .add_attribute("attr1", "🦄") + .add_attribute("attr2", "🌈"), + ) + .add_attribute("attr3", "🐙") + .add_attribute_plaintext("attr4", "🦄")), + ExecuteMsg::AddMoreMixedAttributesAndEvents {} => Ok(Response::new() + .add_event( + Event::new("cyber2".to_string()) + .add_attribute("attr5", "🐙") + .add_attribute("attr6", "🦄"), + ) + .add_attribute("attr7", "😅") + .add_attribute_plaintext("attr8", "🦄")), + ExecuteMsg::AddAttributesFromV010 { + addr, + code_hash, + id, + } => Ok(Response::new() + .add_submessage(SubMsg { + id, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash, + contract_addr: addr, + msg: Binary::from(r#"{"add_more_attributes":{}}"#.as_bytes().to_vec()), + funds: vec![], + }) + .into(), + reply_on: match id { + 0 => ReplyOn::Never, + _ => ReplyOn::Always, + }, + gas_limit: None, + }) + .add_event( + Event::new("cyber1".to_string()) + .add_attribute("attr1", "🦄") + .add_attribute("attr2", "🌈"), + ) + .add_attribute("attr3", "🐙") + .add_attribute_plaintext("attr4", "🦄")), + ExecuteMsg::GasMeter {} => { + // busy work + let mut v = vec![0; 65536]; + let mut x = 0; + loop { + x += (x + 1) % 65536; + v[x] = 65536 - x; + } + } + ExecuteMsg::GasMeterProxy {} => Ok(Response::default()), + ExecuteMsg::TransferMoney { amount } => transfer_money(deps, amount), + ExecuteMsg::RecursiveReply {} => recursive_reply(env, deps), + ExecuteMsg::RecursiveReplyFail {} => recursive_reply_fail(env, deps), + ExecuteMsg::InitNewContract {} => init_new_contract(env, deps), + ExecuteMsg::InitNewContractWithError {} => init_new_contract_with_error(env, deps), + ExecuteMsg::SubMsgLoop { iter } => sub_msg_loop(env, deps, iter), + ExecuteMsg::SubMsgLoopIner { iter } => sub_msg_loop_iner(env, deps, iter), + ExecuteMsg::MultipleSubMessages {} => send_multiple_sub_messages(env, deps), + ExecuteMsg::MultipleSubMessagesNoReply {} => send_multiple_sub_messages_no_reply(env, deps), + ExecuteMsg::QuickError {} => { + count(deps.storage).save(&123456)?; + Err(StdError::generic_err("error in execute")) + } + ExecuteMsg::MultipleSubMessagesNoReplyWithError {} => { + send_multiple_sub_messages_no_reply_with_error(env, deps) + } + ExecuteMsg::MultipleSubMessagesNoReplyWithPanic {} => { + send_multiple_sub_messages_no_reply_with_panic(env, deps) + } + ExecuteMsg::MultipleSubMessagesWithReplyWithError {} => { + send_multiple_sub_messages_with_reply_with_error(env, deps) + } + ExecuteMsg::MultipleSubMessagesWithReplyWithPanic {} => { + send_multiple_sub_messages_with_reply_with_panic(env, deps) + } + ExecuteMsg::InitV10 { + counter, + code_id, + code_hash, + } => { + let mut resp = Response::default(); + + let msg = + "{\"init_from_v1\":{\"counter\":".to_string() + counter.to_string().as_str() + "}}"; + resp.messages.push(SubMsg { + id: 1700, + msg: CosmosMsg::Wasm(WasmMsg::Instantiate { + code_hash, + msg: Binary::from(msg.as_bytes().to_vec()), + funds: vec![], + label: "new2231231".to_string(), + code_id, + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Always, + }); + + Ok(resp) + } + ExecuteMsg::ExecV10 { address, code_hash } => { + let mut resp = Response::default(); + + resp.messages.push(SubMsg { + id: 1800, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + msg: Binary::from("{\"execute_from_v1\":{\"counter\":20}}".as_bytes().to_vec()), + contract_addr: address, + code_hash, + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Always, + }); + + Ok(resp) + } + ExecuteMsg::AddAttributeStep1 {} => Ok(Response::new() + .add_submessage(SubMsg { + id: 8451, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + msg: Binary("{\"add_attribute_step2\":{}}".as_bytes().to_vec()), + contract_addr: env.contract.address.into_string(), + code_hash: env.contract.code_hash, + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Success, + }) + .add_attribute_plaintext("attr1", "🦄") + .set_data(to_binary("step1")?)), + ExecuteMsg::AddAttributeStep2 {} => Ok(Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + msg: Binary("{\"add_attribute_step3\":{}}".as_bytes().to_vec()), + contract_addr: env.contract.address.into_string(), + code_hash: env.contract.code_hash, + funds: vec![], + })) + .add_attribute_plaintext("attr2", "🦄") + .set_data(to_binary("step2")?)), + ExecuteMsg::AddAttributeStep3 {} => Ok(Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + msg: Binary("{\"add_attribute_step4\":{}}".as_bytes().to_vec()), + contract_addr: env.contract.address.into_string(), + code_hash: env.contract.code_hash, + funds: vec![], + })) + .add_attribute_plaintext("attr3", "🦄") + .set_data(to_binary("step3")?)), + ExecuteMsg::AddAttributeStep4 {} => Ok(Response::new() + .add_attribute_plaintext("attr4", "🦄") + .set_data(to_binary("step4")?)), + ExecuteMsg::InitV10NoReply { + counter, + code_id, + code_hash, + } => { + let mut resp = Response::default(); + + let msg = + "{\"init_from_v1\":{\"counter\":".to_string() + counter.to_string().as_str() + "}}"; + resp.messages.push(SubMsg { + id: 8888, + msg: CosmosMsg::Wasm(WasmMsg::Instantiate { + code_hash, + msg: Binary::from(msg.as_bytes().to_vec()), + funds: vec![], + label: "new2231231".to_string(), + code_id, + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Never, + }); + + Ok(resp) + } + ExecuteMsg::ExecV10NoReply { address, code_hash } => { + let mut resp = Response::default(); + + resp.messages.push(SubMsg { + id: 8889, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + msg: Binary::from("{\"execute_from_v1\":{\"counter\":20}}".as_bytes().to_vec()), + contract_addr: address, + code_hash, + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Never, + }); + + Ok(resp) + } + ExecuteMsg::QueryV10 { address, code_hash } => { + let response = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { + code_hash, + contract_addr: address, + msg: to_binary(&ExternalMessages::GetCountFromV1 {})?, + }))?; + + match response { + QueryRes::Get { count } => { + let mut resp = Response::default(); + resp.data = Some((count as u32).to_be_bytes().into()); + return Ok(resp); + } + } + } + + ExecuteMsg::InitV10WithError { code_id, code_hash } => { + let mut resp = Response::default(); + + let msg = "{\"init_from_v1_with_error\":{}"; + resp.messages.push(SubMsg { + id: 2000, + msg: CosmosMsg::Wasm(WasmMsg::Instantiate { + code_hash, + msg: Binary::from(msg.as_bytes().to_vec()), + funds: vec![], + label: "new2231231".to_string(), + code_id, + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Always, + }); + + Ok(resp) + } + ExecuteMsg::ExecV10WithError { address, code_hash } => { + let mut resp = Response::default(); + + resp.messages.push(SubMsg { + id: 2100, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + msg: Binary::from("{\"execute_from_v1_with_error\":{}}".as_bytes().to_vec()), + contract_addr: address, + code_hash, + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Always, + }); + + Ok(resp) + } + ExecuteMsg::InitV10NoReplyWithError { code_id, code_hash } => { + let mut resp = Response::default(); + + let msg = "{\"init_from_v1_with_error\":{}}"; + resp.messages.push(SubMsg { + id: 8890, + msg: CosmosMsg::Wasm(WasmMsg::Instantiate { + code_hash, + msg: Binary::from(msg.as_bytes().to_vec()), + funds: vec![], + label: "new2231231".to_string(), + code_id, + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Never, + }); + + Ok(resp) + } + ExecuteMsg::ExecV10NoReplyWithError { address, code_hash } => { + let mut resp = Response::default(); + + resp.messages.push(SubMsg { + id: 8891, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + msg: Binary::from("{\"execute_from_v1_with_error\":{}}".as_bytes().to_vec()), + contract_addr: address, + code_hash, + funds: vec![], + }), + gas_limit: Some(10000000_u64), + reply_on: ReplyOn::Never, + }); + + Ok(resp) + } + ExecuteMsg::QueryV10WithError { address, code_hash } => { + deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { + code_hash, + contract_addr: address, + msg: to_binary(&ExternalMessages::QueryFromV1WithError {})?, + }))?; + + // shouldn't be reachable + Ok(Response::default()) + } + // These were ported from the v0.10 test-contract: + ExecuteMsg::A { + contract_addr, + code_hash, + x, + y, + } => Ok(a(deps, env, contract_addr, code_hash, x, y)), + ExecuteMsg::B { + contract_addr, + code_hash, + x, + y, + } => Ok(b(deps, env, contract_addr, code_hash, x, y)), + ExecuteMsg::C { x, y } => Ok(c(deps, env, x, y)), + ExecuteMsg::UnicodeData {} => Ok(unicode_data(deps, env)), + ExecuteMsg::EmptyLogKeyValue {} => Ok(empty_log_key_value(deps, env)), + ExecuteMsg::EmptyData {} => Ok(empty_data(deps, env)), + ExecuteMsg::NoData {} => Ok(no_data(deps, env)), + ExecuteMsg::ContractError { error_type } => Err(map_string_to_error(error_type)), + ExecuteMsg::NoLogs {} => Ok(Response::default()), + ExecuteMsg::CallbackToInit { code_id, code_hash } => { + Ok(exec_callback_to_init(deps, env, code_id, code_hash)) + } + ExecuteMsg::CallbackBadParams { + contract_addr, + code_hash, + } => Ok(exec_callback_bad_params(contract_addr, code_hash)), + ExecuteMsg::CallbackContractError { + contract_addr, + code_hash, + } => Ok(exec_with_callback_contract_error(contract_addr, code_hash)), + ExecuteMsg::SetState { key, value } => Ok(set_state(deps, key, value)), + ExecuteMsg::GetState { key } => Ok(get_state(deps, key)), + ExecuteMsg::RemoveState { key } => Ok(remove_state(deps, key)), + ExecuteMsg::TestCanonicalizeAddressErrors {} => test_canonicalize_address_errors(deps), + ExecuteMsg::Panic {} => panic!("panic in exec"), + ExecuteMsg::AllocateOnHeap { bytes } => Ok(allocate_on_heap(bytes as usize)), + ExecuteMsg::PassNullPointerToImportsShouldThrow { pass_type } => { + Ok(pass_null_pointer_to_imports_should_throw(deps, pass_type)) + } + ExecuteMsg::SendExternalQuery { to, code_hash } => { + Ok(Response::new().set_data(vec![send_external_query(deps.as_ref(), to, code_hash)])) + } + ExecuteMsg::SendExternalQueryDepthCounter { + to, + code_hash, + depth, + } => Ok( + Response::new().set_data(vec![send_external_query_depth_counter( + deps.as_ref(), + to, + depth, + code_hash, + )]), + ), + ExecuteMsg::SendExternalQueryRecursionLimit { + to, + code_hash, + depth, + } => Ok( + Response::new().set_data(to_binary(&send_external_query_recursion_limit( + deps.as_ref(), + to, + depth, + code_hash, + )?)?), + ), + ExecuteMsg::SendExternalQueryPanic { to, code_hash } => { + send_external_query_panic(deps, to, code_hash) + } + ExecuteMsg::SendExternalQueryError { to, code_hash } => { + send_external_query_stderror(deps, to, code_hash) + } + ExecuteMsg::SendExternalQueryBadAbi { to, code_hash } => { + send_external_query_bad_abi(deps, to, code_hash) + } + ExecuteMsg::SendExternalQueryBadAbiReceiver { to, code_hash } => { + send_external_query_bad_abi_receiver(deps, to, code_hash) + } + ExecuteMsg::LogMsgSender {} => Err(StdError::generic_err("msg.sender not available")), + ExecuteMsg::CallbackToLogMsgSender { to, code_hash } => Ok(Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: to.clone(), + code_hash, + msg: Binary::from(r#"{"log_msg_sender":{}}"#.as_bytes().to_vec()), + funds: vec![], + })) + .add_attribute("hi", "hey")), + ExecuteMsg::DepositToContract {} => Err(StdError::generic_err("cannot accept funds")), + ExecuteMsg::SendFunds { + amount, + from: _, + to, + denom, + } => Ok(Response::new().add_message(CosmosMsg::Bank(BankMsg::Send { + to_address: to, + amount: coins(amount.into(), denom), + }))), + ExecuteMsg::SendFundsToInitCallback { + amount, + denom, + code_id, + code_hash, + } => Ok( + Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Instantiate { + msg: Binary("{\"nop\":{}}".as_bytes().to_vec()), + code_id, + code_hash, + label: String::from("yo"), + funds: coins(amount.into(), denom), + })), + ), + ExecuteMsg::SendFundsToExecCallback { + amount, + denom, + to, + code_hash, + } => Ok( + Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Execute { + msg: Binary("{\"no_data\":{}}".as_bytes().to_vec()), + contract_addr: to, + code_hash, + funds: coins(amount.into(), denom), + })), + ), + ExecuteMsg::Sleep { ms } => { + thread::sleep(time::Duration::from_millis(ms)); + + Ok(Response::new()) + } + ExecuteMsg::WithFloats { x, y } => Ok(Response::new().set_data(use_floats(x, y))), + ExecuteMsg::CallToInit { + code_id, + code_hash, + label, + msg, + } => Ok(Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Instantiate { + code_id, + code_hash, + msg: Binary(msg.as_bytes().into()), + funds: vec![], + label, + })) + .add_attribute("a", "a")), + ExecuteMsg::CallToExec { + addr, + code_hash, + msg, + } => Ok(Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: addr, + code_hash, + msg: Binary(msg.as_bytes().into()), + funds: vec![], + })) + .add_attribute("b", "b")), + ExecuteMsg::CallToQuery { + addr, + code_hash, + msg, + } => { + let answer: u32 = deps + .querier + .query(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr: addr, + code_hash, + msg: Binary::from(msg.as_bytes().to_vec()), + })) + .map_err(|err| { + StdError::generic_err(format!("Got an error from query: {:?}", err)) + })?; + + Ok(Response::new().add_attribute("c", format!("{}", answer))) + } + ExecuteMsg::StoreReallyLongKey {} => { + let mut store = PrefixedStorage::new(deps.storage, b"my_prefix"); + store.set(REALLY_LONG, b"hello"); + Ok(Response::default()) + } + ExecuteMsg::StoreReallyShortKey {} => { + let mut store = PrefixedStorage::new(deps.storage, b"my_prefix"); + store.set(b"a", b"hello"); + Ok(Response::default()) + } + ExecuteMsg::StoreReallyLongValue {} => { + let mut store = PrefixedStorage::new(deps.storage, b"my_prefix"); + store.set(b"hello", REALLY_LONG); + Ok(Response::default()) + } + ExecuteMsg::Secp256k1Verify { + pubkey, + sig, + msg_hash, + iterations, + } => { + let mut res = Ok(Response::new()); + + // loop for benchmarking + for _ in 0..iterations { + res = match deps.api.secp256k1_verify( + msg_hash.as_slice(), + sig.as_slice(), + pubkey.as_slice(), + ) { + Ok(result) => { + Ok(Response::new().add_attribute("result", format!("{}", result))) + } + Err(err) => Err(StdError::generic_err(format!("{:?}", err))), + }; + } + + return res; + } + ExecuteMsg::Secp256k1VerifyFromCrate { + pubkey, + sig, + msg_hash, + iterations, + } => { + let mut res = Ok(Response::new()); + + // loop for benchmarking + for _ in 0..iterations { + let secp256k1_verifier = Secp256k1::verification_only(); + + let secp256k1_signature = + secp256k1::Signature::from_compact(&sig.0).map_err(|err| { + StdError::generic_err(format!("Malformed signature: {:?}", err)) + })?; + let secp256k1_pubkey = secp256k1::PublicKey::from_slice(pubkey.0.as_slice()) + .map_err(|err| StdError::generic_err(format!("Malformed pubkey: {:?}", err)))?; + let secp256k1_msg = + secp256k1::Message::from_slice(&msg_hash.as_slice()).map_err(|err| { + StdError::generic_err(format!( + "Failed to create a secp256k1 message from signed_bytes: {:?}", + err + )) + })?; + + res = match secp256k1_verifier.verify( + &secp256k1_msg, + &secp256k1_signature, + &secp256k1_pubkey, + ) { + Ok(()) => Ok(Response::new().add_attribute("result", "true")), + Err(_err) => Ok(Response::new().add_attribute("result", "false")), + }; + } + + return res; + } + ExecuteMsg::Ed25519Verify { + pubkey, + sig, + msg, + iterations, + } => { + let mut res = Ok(Response::new()); + + // loop for benchmarking + for _ in 0..iterations { + res = + match deps + .api + .ed25519_verify(msg.as_slice(), sig.as_slice(), pubkey.as_slice()) + { + Ok(result) => { + Ok(Response::new().add_attribute("result", format!("{}", result))) + } + Err(err) => Err(StdError::generic_err(format!("{:?}", err))), + }; + } + + return res; + } + ExecuteMsg::Ed25519BatchVerify { + pubkeys, + sigs, + msgs, + iterations, + } => { + let mut res = Ok(Response::new()); + + // loop for benchmarking + for _ in 0..iterations { + res = match deps.api.ed25519_batch_verify( + msgs.iter() + .map(|m| m.as_slice()) + .collect::>() + .as_slice(), + sigs.iter() + .map(|s| s.as_slice()) + .collect::>() + .as_slice(), + pubkeys + .iter() + .map(|p| p.as_slice()) + .collect::>() + .as_slice(), + ) { + Ok(result) => { + Ok(Response::new().add_attribute("result", format!("{}", result))) + } + Err(err) => Err(StdError::generic_err(format!("{:?}", err))), + }; + } + + return res; + } + ExecuteMsg::Secp256k1RecoverPubkey { + msg_hash, + sig, + recovery_param, + iterations, + } => { + let mut res = Ok(Response::new()); + + // loop for benchmarking + for _ in 0..iterations { + res = match deps.api.secp256k1_recover_pubkey( + msg_hash.as_slice(), + sig.as_slice(), + recovery_param, + ) { + Ok(result) => Ok(Response::new() + .add_attribute("result", format!("{}", Binary(result).to_base64()))), + Err(err) => Err(StdError::generic_err(format!("{:?}", err))), + }; + } + + return res; + } + ExecuteMsg::Secp256k1Sign { + msg, + privkey, + iterations, + } => { + let mut res = Ok(Response::new()); + + // loop for benchmarking + for _ in 0..iterations { + res = match deps.api.secp256k1_sign(msg.as_slice(), privkey.as_slice()) { + Ok(result) => Ok(Response::new() + .add_attribute("result", format!("{}", Binary(result).to_base64()))), + Err(err) => Err(StdError::generic_err(format!("{:?}", err))), + }; + } + + return res; + } + ExecuteMsg::Ed25519Sign { + msg, + privkey, + iterations, + } => { + let mut res = Ok(Response::new()); + + // loop for benchmarking + for _ in 0..iterations { + res = match deps.api.ed25519_sign(msg.as_slice(), privkey.as_slice()) { + Ok(result) => Ok(Response::new() + .add_attribute("result", format!("{}", Binary(result).to_base64()))), + Err(err) => Err(StdError::generic_err(format!("{:?}", err))), + }; + } + + return res; + } + ExecuteMsg::BankMsgSend { to, amount } => { + Ok(Response::new().add_message(CosmosMsg::Bank(BankMsg::Send { + to_address: to, + amount, + }))) + } + ExecuteMsg::BankMsgBurn { amount } => { + Ok(Response::new().add_message(CosmosMsg::Bank(BankMsg::Burn { amount }))) + } + ExecuteMsg::CosmosMsgCustom {} => { + Ok(Response::new().add_message(CosmosMsg::Custom(Empty {}))) + } + ExecuteMsg::SendMultipleFundsToInitCallback { + coins, + code_id, + code_hash, + } => Ok( + Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Instantiate { + code_id, + code_hash, + msg: Binary("{\"nop\":{}}".as_bytes().to_vec()), + funds: coins, + label: "test".to_string(), + })), + ), + ExecuteMsg::SendMultipleFundsToExecCallback { + coins, + to, + code_hash, + } => Ok( + Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: to, + code_hash, + msg: Binary("{\"no_data\":{}}".as_bytes().to_vec()), + funds: coins, + })), + ), + ExecuteMsg::ValidateAddress { addr } => match deps.api.addr_validate(addr.as_str()) { + Ok(a) => Ok(Response::new().set_data(a.as_bytes())), + Err(_) => Ok(Response::new().set_data(to_binary("Apple")?)), + }, + ExecuteMsg::GetEnv {} => { + Ok(Response::new().add_attribute("env", serde_json_wasm::to_string(&env).unwrap())) + } + ExecuteMsg::ExecuteMultipleContracts { details } => { + if details.len() == 0 { + return Ok(Response::default().set_data(env.contract.address.as_bytes())); + } + + if details[0].should_error { + return Err(StdError::generic_err("Error by request")); + } + + Ok(Response::new() + .add_submessage(SubMsg { + id: details[0].msg_id, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + code_hash: details[0].contract_hash.clone(), + contract_addr: details[0].contract_address.clone(), + msg: Binary( + format!( + r#"{{"execute_multiple_contracts":{{"details":{}}}}}"#, + serde_json_wasm::to_string(&details[1..].to_vec()).unwrap(), + ) + .into_bytes(), + ), + funds: vec![], + }) + .into(), + reply_on: match details[0].msg_id { + 0 => ReplyOn::Never, + _ => ReplyOn::Always, + }, + gas_limit: None, + }) + .set_data(details[0].data.as_bytes())) + } + ExecuteMsg::IBCLifecycleComplete(IBCLifecycleComplete::IBCAck { + channel, + sequence, + ack, + success, + }) => Ok(Response::default().add_attributes(vec![ + ("ibc_lifecycle_complete.ibc_ack.channel", channel), + ( + "ibc_lifecycle_complete.ibc_ack.sequence", + sequence.to_string(), + ), + ("ibc_lifecycle_complete.ibc_ack.ack", ack), + ( + "ibc_lifecycle_complete.ibc_ack.success", + success.to_string(), + ), + ])), + ExecuteMsg::IBCLifecycleComplete(IBCLifecycleComplete::IBCTimeout { + channel, + sequence, + }) => Ok(Response::default().add_attributes(vec![ + ("ibc_lifecycle_complete.ibc_timeout.channel", channel), + ( + "ibc_lifecycle_complete.ibc_timeout.sequence", + sequence.to_string(), + ), + ])), } } diff --git a/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/msg.rs b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/msg.rs index 7f96f636a..880e2ddd7 100644 --- a/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/msg.rs +++ b/cosmwasm/contracts/v1/compute-tests/test-compute-contract-v2/src/msg.rs @@ -115,6 +115,8 @@ pub enum InstantiateMsg { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] #[serde(rename_all = "snake_case")] pub enum ExecuteMsg { + Nop {}, + StdError {}, IncrementTimes { times: u64, }, @@ -500,10 +502,3 @@ pub enum ExternalMessages { GetCountFromV1 {}, QueryFromV1WithError {}, } - -#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum MigrateMsg { - Nop {}, - StdError {}, -} diff --git a/cosmwasm/contracts/v1/compute-tests/test-compute-contract/Cargo.lock b/cosmwasm/contracts/v1/compute-tests/test-compute-contract/Cargo.lock index 43b243a3c..546628c80 100644 --- a/cosmwasm/contracts/v1/compute-tests/test-compute-contract/Cargo.lock +++ b/cosmwasm/contracts/v1/compute-tests/test-compute-contract/Cargo.lock @@ -83,53 +83,14 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" -[[package]] -name = "cosmwasm-crypto" -version = "1.1.9" -source = "git+https://github.com/scrtlabs/cosmwasm?rev=46a0be1de3b3c4f45d502d31cd08c258598c54be#46a0be1de3b3c4f45d502d31cd08c258598c54be" -dependencies = [ - "digest 0.10.6", - "ed25519-zebra", - "k256", - "rand_core 0.6.4", - "thiserror", -] - [[package]] name = "cosmwasm-derive" -version = "1.1.9" -source = "git+https://github.com/scrtlabs/cosmwasm?rev=46a0be1de3b3c4f45d502d31cd08c258598c54be#46a0be1de3b3c4f45d502d31cd08c258598c54be" +version = "1.1.10" +source = "git+https://github.com/scrtlabs/cosmwasm?rev=c91d5f2#c91d5f2e8bf0d69cb40ca95e0ce9946fb084b628" dependencies = [ "syn 1.0.109", ] -[[package]] -name = "cosmwasm-std" -version = "1.1.9" -source = "git+https://github.com/scrtlabs/cosmwasm?rev=46a0be1de3b3c4f45d502d31cd08c258598c54be#46a0be1de3b3c4f45d502d31cd08c258598c54be" -dependencies = [ - "base64", - "cosmwasm-crypto", - "cosmwasm-derive", - "derivative", - "forward_ref", - "hex", - "schemars", - "serde", - "serde-json-wasm 0.4.1", - "thiserror", - "uint", -] - -[[package]] -name = "cosmwasm-storage" -version = "1.1.9" -source = "git+https://github.com/scrtlabs/cosmwasm?rev=46a0be1de3b3c4f45d502d31cd08c258598c54be#46a0be1de3b3c4f45d502d31cd08c258598c54be" -dependencies = [ - "cosmwasm-std", - "serde", -] - [[package]] name = "cpufeatures" version = "0.2.6" @@ -498,6 +459,45 @@ dependencies = [ "cc", ] +[[package]] +name = "secret-cosmwasm-crypto" +version = "1.1.10" +source = "git+https://github.com/scrtlabs/cosmwasm?rev=c91d5f2#c91d5f2e8bf0d69cb40ca95e0ce9946fb084b628" +dependencies = [ + "digest 0.10.6", + "ed25519-zebra", + "k256", + "rand_core 0.6.4", + "thiserror", +] + +[[package]] +name = "secret-cosmwasm-std" +version = "1.1.10" +source = "git+https://github.com/scrtlabs/cosmwasm?rev=c91d5f2#c91d5f2e8bf0d69cb40ca95e0ce9946fb084b628" +dependencies = [ + "base64", + "cosmwasm-derive", + "derivative", + "forward_ref", + "hex", + "schemars", + "secret-cosmwasm-crypto", + "serde", + "serde-json-wasm 0.4.1", + "thiserror", + "uint", +] + +[[package]] +name = "secret-cosmwasm-storage" +version = "1.1.10" +source = "git+https://github.com/scrtlabs/cosmwasm?rev=c91d5f2#c91d5f2e8bf0d69cb40ca95e0ce9946fb084b628" +dependencies = [ + "secret-cosmwasm-std", + "serde", +] + [[package]] name = "serde" version = "1.0.159" @@ -685,10 +685,10 @@ name = "v1-sanity-contract" version = "0.0.1" dependencies = [ "bincode2", - "cosmwasm-std", - "cosmwasm-storage", "schemars", "secp256k1", + "secret-cosmwasm-std", + "secret-cosmwasm-storage", "serde", "serde-json-wasm 0.2.3", ] diff --git a/cosmwasm/contracts/v1/compute-tests/test-compute-contract/Cargo.toml b/cosmwasm/contracts/v1/compute-tests/test-compute-contract/Cargo.toml index 231a6f569..88417dece 100644 --- a/cosmwasm/contracts/v1/compute-tests/test-compute-contract/Cargo.toml +++ b/cosmwasm/contracts/v1/compute-tests/test-compute-contract/Cargo.toml @@ -31,9 +31,8 @@ backtraces = ["cosmwasm-std/backtraces"] with_floats = [] [dependencies] -cosmwasm-std = { git = "https://github.com/scrtlabs/cosmwasm", rev = "46a0be1de3b3c4f45d502d31cd08c258598c54be", package = "cosmwasm-std" } -cosmwasm-storage = { git = "https://github.com/scrtlabs/cosmwasm", rev = "46a0be1de3b3c4f45d502d31cd08c258598c54be", package = "cosmwasm-storage" } - +cosmwasm-std = { git = "https://github.com/scrtlabs/cosmwasm", rev = "c91d5f2", package = "secret-cosmwasm-std" } +cosmwasm-storage = { git = "https://github.com/scrtlabs/cosmwasm", rev = "c91d5f2", package = "secret-cosmwasm-storage" } schemars = "0.8.1" serde = { version = "1.0.114", default-features = false, features = [ "derive", diff --git a/x/compute/internal/keeper/testdata/v1-contract-v2.wasm b/x/compute/internal/keeper/testdata/v1-contract-v2.wasm index df33435ab366e49208959c04714a337ca3c24d3b..89ec6820a272ba5afb05b73da22c55abdb15b883 100755 GIT binary patch delta 334215 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 z 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