diff --git a/.gitignore b/.gitignore index 0eb8bca1a..db36a1763 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,8 @@ release/ .hypothesis evm/artifacts evm/cache +evm/.deploys/ +evm/contracts/*/artifacts evm/node_modules evm/package-lock.json prod-sim/deskAlice diff --git a/Makefile b/Makefile index d27e93590..a659d2d99 100644 --- a/Makefile +++ b/Makefile @@ -127,12 +127,6 @@ proto-update-deps: mock-clean-all: @find . -type f -name "*.go" -path "*/mocks/*" -exec rm -f {} + -mock-gen-app: - @go run github.com/vektra/mockery/v2 --name=StakingKeeper --dir=$(CURDIR)/app/ --recursive --output=./app/mocks - @go run github.com/vektra/mockery/v2 --name=BridgeKeeper --dir=$(CURDIR)/app/ --recursive --output=./app/mocks - @go run github.com/vektra/mockery/v2 --name=OracleKeeper --dir=$(CURDIR)/app/ --recursive --output=./app/mocks - - mock-gen-bridge: @go run github.com/vektra/mockery/v2 --name=StakingKeeper --dir=$(CURDIR)/x/bridge/types --recursive --output=./x/bridge/mocks @go run github.com/vektra/mockery/v2 --name=AccountKeeper --dir=$(CURDIR)/x/bridge/types --recursive --output=./x/bridge/mocks @@ -180,6 +174,13 @@ mock-gen-daemon: @go run github.com/vektra/mockery/v2 --name=QueryClient --dir=$(CURDIR)/testutil/grpc --recursive --output=$(CURDIR)/daemons/mocks @go run github.com/vektra/mockery/v2 --name=RequestHandler --dir=$(CURDIR)/daemons/types --recursive --output=$(CURDIR)/daemons/mocks @go run github.com/vektra/mockery/v2 --name=TimeProvider --dir=$(CURDIR)/lib/time --recursive --output=$(CURDIR)/daemons/mocks + +mock-gen-app: + @go run github.com/vektra/mockery/v2 --name=StakingKeeper --dir=$(CURDIR)/app/ --recursive --output=./app/mocks + @go run github.com/vektra/mockery/v2 --name=BridgeKeeper --dir=$(CURDIR)/app/ --recursive --output=./app/mocks + @go run github.com/vektra/mockery/v2 --name=OracleKeeper --dir=$(CURDIR)/app/ --recursive --output=./app/mocks + @go run github.com/vektra/mockery/v2 --name=Keyring --dir=$(GOPATH)/pkg/mod/github.com/cosmos/cosmos-sdk@$(COSMOS_VERSION)/crypto/keyring --recursive --output=./app/mocks + mock-gen: $(MAKE) mock-gen-bridge $(MAKE) mock-gen-dispute diff --git a/adr/adr2001 - trb bridge structure.md b/adr/adr2001 - trb bridge structure.md index c2c74add2..dad2d3a3e 100644 --- a/adr/adr2001 - trb bridge structure.md +++ b/adr/adr2001 - trb bridge structure.md @@ -1,8 +1,9 @@ # ADR 2001: TRB bridge structure ## Authors -@themandalore +@themandalore @brendaloya +@tkernell ## Changelog @@ -11,6 +12,7 @@ - 2024-08-12: spelling - 2024-08-20: added the claim deposit tip +- 2024-08-29: add separate withdraw and deposit limits and minimum deposit amount ## Context Tellor Tributes (TRB) is the tellor token. It exists on Ethereum and cannot be changed. It mints ~4k to the team each month and ~4k to the oracle contract for time based inflationary rewards (tbr). When starting Layer we will launch a bridging contract where parties can deposit TRB to Layer. Layer will utilize reporters then to report deposit events to itself. When the deposit is made it will be assigned a deposit ID and an event will be kicked off. All reporters will report for that event for a 1 hour window (this is allowed so that reporters are able to wait a certain amount of blocks before reporting so that the state of Ethereum has reached a high level of finality) and then we will optimistically use the report in our system, ensuring that the report is at least 12 hours old before the tokens are minted on Layer. Once the value is 12 hours old anyone can mint the tokens on Layer for the specified deposit ID. @@ -20,10 +22,11 @@ Claiming the deposit on Layer costs gas. A party bridging TRB to Layer for the f ![ ADR2001](./graphics/adr2001.png) -As an additional security measure, the bridge contract will not allow more than 20% of the total supply on Layer to be bridged within a 12 hour period (the function will be locked). This will be to ensure that someone does not bridge over a very large amount to stake/grief the network, manipulate votes, or grief the system via disputes without proper time to analyze the situation. For the reverse direction, parties will burn TRB on Layer, the validators will then attest that it happened and then the bridge contract on Ethereum can use the tellor data as any other user, but this time reading burn events. A 20% withdraw limit is also used in this direction and the bridge contract will also use the data optimistically (12 hours old) to further reduce attack vectors. +As an additional security measure, the bridge contract will not allow more than 20% of the total supply on Layer to be bridged to Layer within a 12 hour period (the function will be locked). This will be to ensure that someone does not bridge over a very large amount to stake/grief the network, manipulate votes, or grief the system via disputes without proper time to analyze the situation. The bridge contract also enforces a minimum deposit amount of 0.1 TRB to prevent spamming the bridge with small deposits. For the reverse direction, parties will burn TRB on Layer, the validators will then attest that it happened and then the bridge contract on Ethereum can use the tellor data as any other user, but this time reading burn events. A 5% withdraw limit per 12 hours is used in this direction and the bridge contract will also use the data optimistically (12 hours old) to further reduce attack vectors. The 5% withdraw limit mitigates the worst case scenario where a supermajority of the reporter set is compromised, allowing time to react and coordinate a social fork. The cycle list helps keep the network alive by providing a list of data requests that reporters can support to receive time-based rewards(inflationary rewards) when there are no tips available to claim. Each data request on the cycle list rotates over time so that each request gets pushed on chain on a regular basis. The bridge deposit data request will not appear in the "next request" of the cycle list, however reporters will be allowed to report for it and claim time based rewards for it. Time based rewards will be split between the data request on the cycle list and the bridged deposit request. Parties can also use the tip functionality to incentivize faster updates for deposits. + ![ ADR1003](./graphics/adr1003.png) ## Alternative Approaches diff --git a/adr/graphics/adr2001.png b/adr/graphics/adr2001.png index 5461c09fa..174d71a82 100644 Binary files a/adr/graphics/adr2001.png and b/adr/graphics/adr2001.png differ diff --git a/api/layer/bridge/tx.pulsar.go b/api/layer/bridge/tx.pulsar.go index 3a2b5d0e0..5c37f3e25 100644 --- a/api/layer/bridge/tx.pulsar.go +++ b/api/layer/bridge/tx.pulsar.go @@ -1838,30 +1838,122 @@ func (x *fastReflection_MsgWithdrawTokensResponse) ProtoMethods() *protoiface.Me } } +var _ protoreflect.List = (*_MsgClaimDepositsRequest_2_list)(nil) + +type _MsgClaimDepositsRequest_2_list struct { + list *[]uint64 +} + +func (x *_MsgClaimDepositsRequest_2_list) Len() int { + if x.list == nil { + return 0 + } + return len(*x.list) +} + +func (x *_MsgClaimDepositsRequest_2_list) Get(i int) protoreflect.Value { + return protoreflect.ValueOfUint64((*x.list)[i]) +} + +func (x *_MsgClaimDepositsRequest_2_list) Set(i int, value protoreflect.Value) { + valueUnwrapped := value.Uint() + concreteValue := valueUnwrapped + (*x.list)[i] = concreteValue +} + +func (x *_MsgClaimDepositsRequest_2_list) Append(value protoreflect.Value) { + valueUnwrapped := value.Uint() + concreteValue := valueUnwrapped + *x.list = append(*x.list, concreteValue) +} + +func (x *_MsgClaimDepositsRequest_2_list) AppendMutable() protoreflect.Value { + panic(fmt.Errorf("AppendMutable can not be called on message MsgClaimDepositsRequest at list field DepositIds as it is not of Message kind")) +} + +func (x *_MsgClaimDepositsRequest_2_list) Truncate(n int) { + *x.list = (*x.list)[:n] +} + +func (x *_MsgClaimDepositsRequest_2_list) NewElement() protoreflect.Value { + v := uint64(0) + return protoreflect.ValueOfUint64(v) +} + +func (x *_MsgClaimDepositsRequest_2_list) IsValid() bool { + return x.list != nil +} + +var _ protoreflect.List = (*_MsgClaimDepositsRequest_3_list)(nil) + +type _MsgClaimDepositsRequest_3_list struct { + list *[]uint64 +} + +func (x *_MsgClaimDepositsRequest_3_list) Len() int { + if x.list == nil { + return 0 + } + return len(*x.list) +} + +func (x *_MsgClaimDepositsRequest_3_list) Get(i int) protoreflect.Value { + return protoreflect.ValueOfUint64((*x.list)[i]) +} + +func (x *_MsgClaimDepositsRequest_3_list) Set(i int, value protoreflect.Value) { + valueUnwrapped := value.Uint() + concreteValue := valueUnwrapped + (*x.list)[i] = concreteValue +} + +func (x *_MsgClaimDepositsRequest_3_list) Append(value protoreflect.Value) { + valueUnwrapped := value.Uint() + concreteValue := valueUnwrapped + *x.list = append(*x.list, concreteValue) +} + +func (x *_MsgClaimDepositsRequest_3_list) AppendMutable() protoreflect.Value { + panic(fmt.Errorf("AppendMutable can not be called on message MsgClaimDepositsRequest at list field Indices as it is not of Message kind")) +} + +func (x *_MsgClaimDepositsRequest_3_list) Truncate(n int) { + *x.list = (*x.list)[:n] +} + +func (x *_MsgClaimDepositsRequest_3_list) NewElement() protoreflect.Value { + v := uint64(0) + return protoreflect.ValueOfUint64(v) +} + +func (x *_MsgClaimDepositsRequest_3_list) IsValid() bool { + return x.list != nil +} + var ( - md_MsgClaimDepositRequest protoreflect.MessageDescriptor - fd_MsgClaimDepositRequest_creator protoreflect.FieldDescriptor - fd_MsgClaimDepositRequest_deposit_id protoreflect.FieldDescriptor - fd_MsgClaimDepositRequest_index protoreflect.FieldDescriptor + md_MsgClaimDepositsRequest protoreflect.MessageDescriptor + fd_MsgClaimDepositsRequest_creator protoreflect.FieldDescriptor + fd_MsgClaimDepositsRequest_deposit_ids protoreflect.FieldDescriptor + fd_MsgClaimDepositsRequest_indices protoreflect.FieldDescriptor ) func init() { file_layer_bridge_tx_proto_init() - md_MsgClaimDepositRequest = File_layer_bridge_tx_proto.Messages().ByName("MsgClaimDepositRequest") - fd_MsgClaimDepositRequest_creator = md_MsgClaimDepositRequest.Fields().ByName("creator") - fd_MsgClaimDepositRequest_deposit_id = md_MsgClaimDepositRequest.Fields().ByName("deposit_id") - fd_MsgClaimDepositRequest_index = md_MsgClaimDepositRequest.Fields().ByName("index") + md_MsgClaimDepositsRequest = File_layer_bridge_tx_proto.Messages().ByName("MsgClaimDepositsRequest") + fd_MsgClaimDepositsRequest_creator = md_MsgClaimDepositsRequest.Fields().ByName("creator") + fd_MsgClaimDepositsRequest_deposit_ids = md_MsgClaimDepositsRequest.Fields().ByName("deposit_ids") + fd_MsgClaimDepositsRequest_indices = md_MsgClaimDepositsRequest.Fields().ByName("indices") } -var _ protoreflect.Message = (*fastReflection_MsgClaimDepositRequest)(nil) +var _ protoreflect.Message = (*fastReflection_MsgClaimDepositsRequest)(nil) -type fastReflection_MsgClaimDepositRequest MsgClaimDepositRequest +type fastReflection_MsgClaimDepositsRequest MsgClaimDepositsRequest -func (x *MsgClaimDepositRequest) ProtoReflect() protoreflect.Message { - return (*fastReflection_MsgClaimDepositRequest)(x) +func (x *MsgClaimDepositsRequest) ProtoReflect() protoreflect.Message { + return (*fastReflection_MsgClaimDepositsRequest)(x) } -func (x *MsgClaimDepositRequest) slowProtoReflect() protoreflect.Message { +func (x *MsgClaimDepositsRequest) slowProtoReflect() protoreflect.Message { mi := &file_layer_bridge_tx_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1873,43 +1965,43 @@ func (x *MsgClaimDepositRequest) slowProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -var _fastReflection_MsgClaimDepositRequest_messageType fastReflection_MsgClaimDepositRequest_messageType -var _ protoreflect.MessageType = fastReflection_MsgClaimDepositRequest_messageType{} +var _fastReflection_MsgClaimDepositsRequest_messageType fastReflection_MsgClaimDepositsRequest_messageType +var _ protoreflect.MessageType = fastReflection_MsgClaimDepositsRequest_messageType{} -type fastReflection_MsgClaimDepositRequest_messageType struct{} +type fastReflection_MsgClaimDepositsRequest_messageType struct{} -func (x fastReflection_MsgClaimDepositRequest_messageType) Zero() protoreflect.Message { - return (*fastReflection_MsgClaimDepositRequest)(nil) +func (x fastReflection_MsgClaimDepositsRequest_messageType) Zero() protoreflect.Message { + return (*fastReflection_MsgClaimDepositsRequest)(nil) } -func (x fastReflection_MsgClaimDepositRequest_messageType) New() protoreflect.Message { - return new(fastReflection_MsgClaimDepositRequest) +func (x fastReflection_MsgClaimDepositsRequest_messageType) New() protoreflect.Message { + return new(fastReflection_MsgClaimDepositsRequest) } -func (x fastReflection_MsgClaimDepositRequest_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_MsgClaimDepositRequest +func (x fastReflection_MsgClaimDepositsRequest_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_MsgClaimDepositsRequest } // Descriptor returns message descriptor, which contains only the protobuf // type information for the message. -func (x *fastReflection_MsgClaimDepositRequest) Descriptor() protoreflect.MessageDescriptor { - return md_MsgClaimDepositRequest +func (x *fastReflection_MsgClaimDepositsRequest) Descriptor() protoreflect.MessageDescriptor { + return md_MsgClaimDepositsRequest } // Type returns the message type, which encapsulates both Go and protobuf // type information. If the Go type information is not needed, // it is recommended that the message descriptor be used instead. -func (x *fastReflection_MsgClaimDepositRequest) Type() protoreflect.MessageType { - return _fastReflection_MsgClaimDepositRequest_messageType +func (x *fastReflection_MsgClaimDepositsRequest) Type() protoreflect.MessageType { + return _fastReflection_MsgClaimDepositsRequest_messageType } // New returns a newly allocated and mutable empty message. -func (x *fastReflection_MsgClaimDepositRequest) New() protoreflect.Message { - return new(fastReflection_MsgClaimDepositRequest) +func (x *fastReflection_MsgClaimDepositsRequest) New() protoreflect.Message { + return new(fastReflection_MsgClaimDepositsRequest) } // Interface unwraps the message reflection interface and // returns the underlying ProtoMessage interface. -func (x *fastReflection_MsgClaimDepositRequest) Interface() protoreflect.ProtoMessage { - return (*MsgClaimDepositRequest)(x) +func (x *fastReflection_MsgClaimDepositsRequest) Interface() protoreflect.ProtoMessage { + return (*MsgClaimDepositsRequest)(x) } // Range iterates over every populated field in an undefined order, @@ -1917,22 +2009,22 @@ func (x *fastReflection_MsgClaimDepositRequest) Interface() protoreflect.ProtoMe // Range returns immediately if f returns false. // While iterating, mutating operations may only be performed // on the current field descriptor. -func (x *fastReflection_MsgClaimDepositRequest) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { +func (x *fastReflection_MsgClaimDepositsRequest) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { if x.Creator != "" { value := protoreflect.ValueOfString(x.Creator) - if !f(fd_MsgClaimDepositRequest_creator, value) { + if !f(fd_MsgClaimDepositsRequest_creator, value) { return } } - if x.DepositId != uint64(0) { - value := protoreflect.ValueOfUint64(x.DepositId) - if !f(fd_MsgClaimDepositRequest_deposit_id, value) { + if len(x.DepositIds) != 0 { + value := protoreflect.ValueOfList(&_MsgClaimDepositsRequest_2_list{list: &x.DepositIds}) + if !f(fd_MsgClaimDepositsRequest_deposit_ids, value) { return } } - if x.Index != uint64(0) { - value := protoreflect.ValueOfUint64(x.Index) - if !f(fd_MsgClaimDepositRequest_index, value) { + if len(x.Indices) != 0 { + value := protoreflect.ValueOfList(&_MsgClaimDepositsRequest_3_list{list: &x.Indices}) + if !f(fd_MsgClaimDepositsRequest_indices, value) { return } } @@ -1949,19 +2041,19 @@ func (x *fastReflection_MsgClaimDepositRequest) Range(f func(protoreflect.FieldD // In other cases (aside from the nullable cases above), // a proto3 scalar field is populated if it contains a non-zero value, and // a repeated field is populated if it is non-empty. -func (x *fastReflection_MsgClaimDepositRequest) Has(fd protoreflect.FieldDescriptor) bool { +func (x *fastReflection_MsgClaimDepositsRequest) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { - case "layer.bridge.MsgClaimDepositRequest.creator": + case "layer.bridge.MsgClaimDepositsRequest.creator": return x.Creator != "" - case "layer.bridge.MsgClaimDepositRequest.deposit_id": - return x.DepositId != uint64(0) - case "layer.bridge.MsgClaimDepositRequest.index": - return x.Index != uint64(0) + case "layer.bridge.MsgClaimDepositsRequest.deposit_ids": + return len(x.DepositIds) != 0 + case "layer.bridge.MsgClaimDepositsRequest.indices": + return len(x.Indices) != 0 default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: layer.bridge.MsgClaimDepositRequest")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: layer.bridge.MsgClaimDepositsRequest")) } - panic(fmt.Errorf("message layer.bridge.MsgClaimDepositRequest does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message layer.bridge.MsgClaimDepositsRequest does not contain field %s", fd.FullName())) } } @@ -1971,19 +2063,19 @@ func (x *fastReflection_MsgClaimDepositRequest) Has(fd protoreflect.FieldDescrip // associated with the given field number. // // Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgClaimDepositRequest) Clear(fd protoreflect.FieldDescriptor) { +func (x *fastReflection_MsgClaimDepositsRequest) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { - case "layer.bridge.MsgClaimDepositRequest.creator": + case "layer.bridge.MsgClaimDepositsRequest.creator": x.Creator = "" - case "layer.bridge.MsgClaimDepositRequest.deposit_id": - x.DepositId = uint64(0) - case "layer.bridge.MsgClaimDepositRequest.index": - x.Index = uint64(0) + case "layer.bridge.MsgClaimDepositsRequest.deposit_ids": + x.DepositIds = nil + case "layer.bridge.MsgClaimDepositsRequest.indices": + x.Indices = nil default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: layer.bridge.MsgClaimDepositRequest")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: layer.bridge.MsgClaimDepositsRequest")) } - panic(fmt.Errorf("message layer.bridge.MsgClaimDepositRequest does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message layer.bridge.MsgClaimDepositsRequest does not contain field %s", fd.FullName())) } } @@ -1993,22 +2085,28 @@ func (x *fastReflection_MsgClaimDepositRequest) Clear(fd protoreflect.FieldDescr // the default value of a bytes scalar is guaranteed to be a copy. // For unpopulated composite types, it returns an empty, read-only view // of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_MsgClaimDepositRequest) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { +func (x *fastReflection_MsgClaimDepositsRequest) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { switch descriptor.FullName() { - case "layer.bridge.MsgClaimDepositRequest.creator": + case "layer.bridge.MsgClaimDepositsRequest.creator": value := x.Creator return protoreflect.ValueOfString(value) - case "layer.bridge.MsgClaimDepositRequest.deposit_id": - value := x.DepositId - return protoreflect.ValueOfUint64(value) - case "layer.bridge.MsgClaimDepositRequest.index": - value := x.Index - return protoreflect.ValueOfUint64(value) + case "layer.bridge.MsgClaimDepositsRequest.deposit_ids": + if len(x.DepositIds) == 0 { + return protoreflect.ValueOfList(&_MsgClaimDepositsRequest_2_list{}) + } + listValue := &_MsgClaimDepositsRequest_2_list{list: &x.DepositIds} + return protoreflect.ValueOfList(listValue) + case "layer.bridge.MsgClaimDepositsRequest.indices": + if len(x.Indices) == 0 { + return protoreflect.ValueOfList(&_MsgClaimDepositsRequest_3_list{}) + } + listValue := &_MsgClaimDepositsRequest_3_list{list: &x.Indices} + return protoreflect.ValueOfList(listValue) default: if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: layer.bridge.MsgClaimDepositRequest")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: layer.bridge.MsgClaimDepositsRequest")) } - panic(fmt.Errorf("message layer.bridge.MsgClaimDepositRequest does not contain field %s", descriptor.FullName())) + panic(fmt.Errorf("message layer.bridge.MsgClaimDepositsRequest does not contain field %s", descriptor.FullName())) } } @@ -2022,19 +2120,23 @@ func (x *fastReflection_MsgClaimDepositRequest) Get(descriptor protoreflect.Fiel // empty, read-only value, then it panics. // // Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgClaimDepositRequest) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { +func (x *fastReflection_MsgClaimDepositsRequest) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { switch fd.FullName() { - case "layer.bridge.MsgClaimDepositRequest.creator": + case "layer.bridge.MsgClaimDepositsRequest.creator": x.Creator = value.Interface().(string) - case "layer.bridge.MsgClaimDepositRequest.deposit_id": - x.DepositId = value.Uint() - case "layer.bridge.MsgClaimDepositRequest.index": - x.Index = value.Uint() + case "layer.bridge.MsgClaimDepositsRequest.deposit_ids": + lv := value.List() + clv := lv.(*_MsgClaimDepositsRequest_2_list) + x.DepositIds = *clv.list + case "layer.bridge.MsgClaimDepositsRequest.indices": + lv := value.List() + clv := lv.(*_MsgClaimDepositsRequest_3_list) + x.Indices = *clv.list default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: layer.bridge.MsgClaimDepositRequest")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: layer.bridge.MsgClaimDepositsRequest")) } - panic(fmt.Errorf("message layer.bridge.MsgClaimDepositRequest does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message layer.bridge.MsgClaimDepositsRequest does not contain field %s", fd.FullName())) } } @@ -2048,48 +2150,58 @@ func (x *fastReflection_MsgClaimDepositRequest) Set(fd protoreflect.FieldDescrip // It panics if the field does not contain a composite type. // // Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgClaimDepositRequest) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { +func (x *fastReflection_MsgClaimDepositsRequest) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "layer.bridge.MsgClaimDepositRequest.creator": - panic(fmt.Errorf("field creator of message layer.bridge.MsgClaimDepositRequest is not mutable")) - case "layer.bridge.MsgClaimDepositRequest.deposit_id": - panic(fmt.Errorf("field deposit_id of message layer.bridge.MsgClaimDepositRequest is not mutable")) - case "layer.bridge.MsgClaimDepositRequest.index": - panic(fmt.Errorf("field index of message layer.bridge.MsgClaimDepositRequest is not mutable")) + case "layer.bridge.MsgClaimDepositsRequest.deposit_ids": + if x.DepositIds == nil { + x.DepositIds = []uint64{} + } + value := &_MsgClaimDepositsRequest_2_list{list: &x.DepositIds} + return protoreflect.ValueOfList(value) + case "layer.bridge.MsgClaimDepositsRequest.indices": + if x.Indices == nil { + x.Indices = []uint64{} + } + value := &_MsgClaimDepositsRequest_3_list{list: &x.Indices} + return protoreflect.ValueOfList(value) + case "layer.bridge.MsgClaimDepositsRequest.creator": + panic(fmt.Errorf("field creator of message layer.bridge.MsgClaimDepositsRequest is not mutable")) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: layer.bridge.MsgClaimDepositRequest")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: layer.bridge.MsgClaimDepositsRequest")) } - panic(fmt.Errorf("message layer.bridge.MsgClaimDepositRequest does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message layer.bridge.MsgClaimDepositsRequest does not contain field %s", fd.FullName())) } } // NewField returns a new value that is assignable to the field // for the given descriptor. For scalars, this returns the default value. // For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_MsgClaimDepositRequest) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { +func (x *fastReflection_MsgClaimDepositsRequest) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "layer.bridge.MsgClaimDepositRequest.creator": + case "layer.bridge.MsgClaimDepositsRequest.creator": return protoreflect.ValueOfString("") - case "layer.bridge.MsgClaimDepositRequest.deposit_id": - return protoreflect.ValueOfUint64(uint64(0)) - case "layer.bridge.MsgClaimDepositRequest.index": - return protoreflect.ValueOfUint64(uint64(0)) + case "layer.bridge.MsgClaimDepositsRequest.deposit_ids": + list := []uint64{} + return protoreflect.ValueOfList(&_MsgClaimDepositsRequest_2_list{list: &list}) + case "layer.bridge.MsgClaimDepositsRequest.indices": + list := []uint64{} + return protoreflect.ValueOfList(&_MsgClaimDepositsRequest_3_list{list: &list}) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: layer.bridge.MsgClaimDepositRequest")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: layer.bridge.MsgClaimDepositsRequest")) } - panic(fmt.Errorf("message layer.bridge.MsgClaimDepositRequest does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message layer.bridge.MsgClaimDepositsRequest does not contain field %s", fd.FullName())) } } // WhichOneof reports which field within the oneof is populated, // returning nil if none are populated. // It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_MsgClaimDepositRequest) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { +func (x *fastReflection_MsgClaimDepositsRequest) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { switch d.FullName() { default: - panic(fmt.Errorf("%s is not a oneof field in layer.bridge.MsgClaimDepositRequest", d.FullName())) + panic(fmt.Errorf("%s is not a oneof field in layer.bridge.MsgClaimDepositsRequest", d.FullName())) } panic("unreachable") } @@ -2097,7 +2209,7 @@ func (x *fastReflection_MsgClaimDepositRequest) WhichOneof(d protoreflect.OneofD // GetUnknown retrieves the entire list of unknown fields. // The caller may only mutate the contents of the RawFields // if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_MsgClaimDepositRequest) GetUnknown() protoreflect.RawFields { +func (x *fastReflection_MsgClaimDepositsRequest) GetUnknown() protoreflect.RawFields { return x.unknownFields } @@ -2108,7 +2220,7 @@ func (x *fastReflection_MsgClaimDepositRequest) GetUnknown() protoreflect.RawFie // An empty RawFields may be passed to clear the fields. // // SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgClaimDepositRequest) SetUnknown(fields protoreflect.RawFields) { +func (x *fastReflection_MsgClaimDepositsRequest) SetUnknown(fields protoreflect.RawFields) { x.unknownFields = fields } @@ -2120,7 +2232,7 @@ func (x *fastReflection_MsgClaimDepositRequest) SetUnknown(fields protoreflect.R // message type, but the details are implementation dependent. // Validity is not part of the protobuf data model, and may not // be preserved in marshaling or other operations. -func (x *fastReflection_MsgClaimDepositRequest) IsValid() bool { +func (x *fastReflection_MsgClaimDepositsRequest) IsValid() bool { return x != nil } @@ -2130,9 +2242,9 @@ func (x *fastReflection_MsgClaimDepositRequest) IsValid() bool { // The returned methods type is identical to // "google.golang.org/protobuf/runtime/protoiface".Methods. // Consult the protoiface package documentation for details. -func (x *fastReflection_MsgClaimDepositRequest) ProtoMethods() *protoiface.Methods { +func (x *fastReflection_MsgClaimDepositsRequest) ProtoMethods() *protoiface.Methods { size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*MsgClaimDepositRequest) + x := input.Message.Interface().(*MsgClaimDepositsRequest) if x == nil { return protoiface.SizeOutput{ NoUnkeyedLiterals: input.NoUnkeyedLiterals, @@ -2148,11 +2260,19 @@ func (x *fastReflection_MsgClaimDepositRequest) ProtoMethods() *protoiface.Metho if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } - if x.DepositId != 0 { - n += 1 + runtime.Sov(uint64(x.DepositId)) + if len(x.DepositIds) > 0 { + l = 0 + for _, e := range x.DepositIds { + l += runtime.Sov(uint64(e)) + } + n += 1 + runtime.Sov(uint64(l)) + l } - if x.Index != 0 { - n += 1 + runtime.Sov(uint64(x.Index)) + if len(x.Indices) > 0 { + l = 0 + for _, e := range x.Indices { + l += runtime.Sov(uint64(e)) + } + n += 1 + runtime.Sov(uint64(l)) + l } if x.unknownFields != nil { n += len(x.unknownFields) @@ -2164,7 +2284,7 @@ func (x *fastReflection_MsgClaimDepositRequest) ProtoMethods() *protoiface.Metho } marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*MsgClaimDepositRequest) + x := input.Message.Interface().(*MsgClaimDepositsRequest) if x == nil { return protoiface.MarshalOutput{ NoUnkeyedLiterals: input.NoUnkeyedLiterals, @@ -2183,15 +2303,45 @@ func (x *fastReflection_MsgClaimDepositRequest) ProtoMethods() *protoiface.Metho i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } - if x.Index != 0 { - i = runtime.EncodeVarint(dAtA, i, uint64(x.Index)) + if len(x.Indices) > 0 { + var pksize2 int + for _, num := range x.Indices { + pksize2 += runtime.Sov(uint64(num)) + } + i -= pksize2 + j1 := i + for _, num := range x.Indices { + for num >= 1<<7 { + dAtA[j1] = uint8(uint64(num)&0x7f | 0x80) + num >>= 7 + j1++ + } + dAtA[j1] = uint8(num) + j1++ + } + i = runtime.EncodeVarint(dAtA, i, uint64(pksize2)) i-- - dAtA[i] = 0x18 + dAtA[i] = 0x1a } - if x.DepositId != 0 { - i = runtime.EncodeVarint(dAtA, i, uint64(x.DepositId)) + if len(x.DepositIds) > 0 { + var pksize4 int + for _, num := range x.DepositIds { + pksize4 += runtime.Sov(uint64(num)) + } + i -= pksize4 + j3 := i + for _, num := range x.DepositIds { + for num >= 1<<7 { + dAtA[j3] = uint8(uint64(num)&0x7f | 0x80) + num >>= 7 + j3++ + } + dAtA[j3] = uint8(num) + j3++ + } + i = runtime.EncodeVarint(dAtA, i, uint64(pksize4)) i-- - dAtA[i] = 0x10 + dAtA[i] = 0x12 } if len(x.Creator) > 0 { i -= len(x.Creator) @@ -2211,7 +2361,7 @@ func (x *fastReflection_MsgClaimDepositRequest) ProtoMethods() *protoiface.Metho }, nil } unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*MsgClaimDepositRequest) + x := input.Message.Interface().(*MsgClaimDepositsRequest) if x == nil { return protoiface.UnmarshalOutput{ NoUnkeyedLiterals: input.NoUnkeyedLiterals, @@ -2243,10 +2393,10 @@ func (x *fastReflection_MsgClaimDepositRequest) ProtoMethods() *protoiface.Metho fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgClaimDepositRequest: wiretype end group for non-group") + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgClaimDepositsRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgClaimDepositRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgClaimDepositsRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -2282,42 +2432,156 @@ func (x *fastReflection_MsgClaimDepositRequest) ProtoMethods() *protoiface.Metho x.Creator = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: - if wireType != 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field DepositId", wireType) - } - x.DepositId = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + if wireType == 0 { + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } } - if iNdEx >= l { + x.DepositIds = append(x.DepositIds, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF } - b := dAtA[iNdEx] - iNdEx++ - x.DepositId |= uint64(b&0x7F) << shift - if b < 0x80 { - break + var elementCount int + var count int + for _, integer := range dAtA[iNdEx:postIndex] { + if integer < 128 { + count++ + } } + elementCount = count + if elementCount != 0 && len(x.DepositIds) == 0 { + x.DepositIds = make([]uint64, 0, elementCount) + } + for iNdEx < postIndex { + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + x.DepositIds = append(x.DepositIds, v) + } + } else { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field DepositIds", wireType) } case 3: - if wireType != 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Index", wireType) - } - x.Index = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + if wireType == 0 { + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } } - if iNdEx >= l { + x.Indices = append(x.Indices, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF } - b := dAtA[iNdEx] - iNdEx++ - x.Index |= uint64(b&0x7F) << shift - if b < 0x80 { - break + var elementCount int + var count int + for _, integer := range dAtA[iNdEx:postIndex] { + if integer < 128 { + count++ + } + } + elementCount = count + if elementCount != 0 && len(x.Indices) == 0 { + x.Indices = make([]uint64, 0, elementCount) } + for iNdEx < postIndex { + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + x.Indices = append(x.Indices, v) + } + } else { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Indices", wireType) } default: iNdEx = preIndex @@ -2355,23 +2619,23 @@ func (x *fastReflection_MsgClaimDepositRequest) ProtoMethods() *protoiface.Metho } var ( - md_MsgClaimDepositResponse protoreflect.MessageDescriptor + md_MsgClaimDepositsResponse protoreflect.MessageDescriptor ) func init() { file_layer_bridge_tx_proto_init() - md_MsgClaimDepositResponse = File_layer_bridge_tx_proto.Messages().ByName("MsgClaimDepositResponse") + md_MsgClaimDepositsResponse = File_layer_bridge_tx_proto.Messages().ByName("MsgClaimDepositsResponse") } -var _ protoreflect.Message = (*fastReflection_MsgClaimDepositResponse)(nil) +var _ protoreflect.Message = (*fastReflection_MsgClaimDepositsResponse)(nil) -type fastReflection_MsgClaimDepositResponse MsgClaimDepositResponse +type fastReflection_MsgClaimDepositsResponse MsgClaimDepositsResponse -func (x *MsgClaimDepositResponse) ProtoReflect() protoreflect.Message { - return (*fastReflection_MsgClaimDepositResponse)(x) +func (x *MsgClaimDepositsResponse) ProtoReflect() protoreflect.Message { + return (*fastReflection_MsgClaimDepositsResponse)(x) } -func (x *MsgClaimDepositResponse) slowProtoReflect() protoreflect.Message { +func (x *MsgClaimDepositsResponse) slowProtoReflect() protoreflect.Message { mi := &file_layer_bridge_tx_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2383,43 +2647,43 @@ func (x *MsgClaimDepositResponse) slowProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -var _fastReflection_MsgClaimDepositResponse_messageType fastReflection_MsgClaimDepositResponse_messageType -var _ protoreflect.MessageType = fastReflection_MsgClaimDepositResponse_messageType{} +var _fastReflection_MsgClaimDepositsResponse_messageType fastReflection_MsgClaimDepositsResponse_messageType +var _ protoreflect.MessageType = fastReflection_MsgClaimDepositsResponse_messageType{} -type fastReflection_MsgClaimDepositResponse_messageType struct{} +type fastReflection_MsgClaimDepositsResponse_messageType struct{} -func (x fastReflection_MsgClaimDepositResponse_messageType) Zero() protoreflect.Message { - return (*fastReflection_MsgClaimDepositResponse)(nil) +func (x fastReflection_MsgClaimDepositsResponse_messageType) Zero() protoreflect.Message { + return (*fastReflection_MsgClaimDepositsResponse)(nil) } -func (x fastReflection_MsgClaimDepositResponse_messageType) New() protoreflect.Message { - return new(fastReflection_MsgClaimDepositResponse) +func (x fastReflection_MsgClaimDepositsResponse_messageType) New() protoreflect.Message { + return new(fastReflection_MsgClaimDepositsResponse) } -func (x fastReflection_MsgClaimDepositResponse_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_MsgClaimDepositResponse +func (x fastReflection_MsgClaimDepositsResponse_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_MsgClaimDepositsResponse } // Descriptor returns message descriptor, which contains only the protobuf // type information for the message. -func (x *fastReflection_MsgClaimDepositResponse) Descriptor() protoreflect.MessageDescriptor { - return md_MsgClaimDepositResponse +func (x *fastReflection_MsgClaimDepositsResponse) Descriptor() protoreflect.MessageDescriptor { + return md_MsgClaimDepositsResponse } // Type returns the message type, which encapsulates both Go and protobuf // type information. If the Go type information is not needed, // it is recommended that the message descriptor be used instead. -func (x *fastReflection_MsgClaimDepositResponse) Type() protoreflect.MessageType { - return _fastReflection_MsgClaimDepositResponse_messageType +func (x *fastReflection_MsgClaimDepositsResponse) Type() protoreflect.MessageType { + return _fastReflection_MsgClaimDepositsResponse_messageType } // New returns a newly allocated and mutable empty message. -func (x *fastReflection_MsgClaimDepositResponse) New() protoreflect.Message { - return new(fastReflection_MsgClaimDepositResponse) +func (x *fastReflection_MsgClaimDepositsResponse) New() protoreflect.Message { + return new(fastReflection_MsgClaimDepositsResponse) } // Interface unwraps the message reflection interface and // returns the underlying ProtoMessage interface. -func (x *fastReflection_MsgClaimDepositResponse) Interface() protoreflect.ProtoMessage { - return (*MsgClaimDepositResponse)(x) +func (x *fastReflection_MsgClaimDepositsResponse) Interface() protoreflect.ProtoMessage { + return (*MsgClaimDepositsResponse)(x) } // Range iterates over every populated field in an undefined order, @@ -2427,7 +2691,7 @@ func (x *fastReflection_MsgClaimDepositResponse) Interface() protoreflect.ProtoM // Range returns immediately if f returns false. // While iterating, mutating operations may only be performed // on the current field descriptor. -func (x *fastReflection_MsgClaimDepositResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { +func (x *fastReflection_MsgClaimDepositsResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { } // Has reports whether a field is populated. @@ -2441,13 +2705,13 @@ func (x *fastReflection_MsgClaimDepositResponse) Range(f func(protoreflect.Field // In other cases (aside from the nullable cases above), // a proto3 scalar field is populated if it contains a non-zero value, and // a repeated field is populated if it is non-empty. -func (x *fastReflection_MsgClaimDepositResponse) Has(fd protoreflect.FieldDescriptor) bool { +func (x *fastReflection_MsgClaimDepositsResponse) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: layer.bridge.MsgClaimDepositResponse")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: layer.bridge.MsgClaimDepositsResponse")) } - panic(fmt.Errorf("message layer.bridge.MsgClaimDepositResponse does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message layer.bridge.MsgClaimDepositsResponse does not contain field %s", fd.FullName())) } } @@ -2457,13 +2721,13 @@ func (x *fastReflection_MsgClaimDepositResponse) Has(fd protoreflect.FieldDescri // associated with the given field number. // // Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgClaimDepositResponse) Clear(fd protoreflect.FieldDescriptor) { +func (x *fastReflection_MsgClaimDepositsResponse) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: layer.bridge.MsgClaimDepositResponse")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: layer.bridge.MsgClaimDepositsResponse")) } - panic(fmt.Errorf("message layer.bridge.MsgClaimDepositResponse does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message layer.bridge.MsgClaimDepositsResponse does not contain field %s", fd.FullName())) } } @@ -2473,13 +2737,13 @@ func (x *fastReflection_MsgClaimDepositResponse) Clear(fd protoreflect.FieldDesc // the default value of a bytes scalar is guaranteed to be a copy. // For unpopulated composite types, it returns an empty, read-only view // of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_MsgClaimDepositResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { +func (x *fastReflection_MsgClaimDepositsResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { switch descriptor.FullName() { default: if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: layer.bridge.MsgClaimDepositResponse")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: layer.bridge.MsgClaimDepositsResponse")) } - panic(fmt.Errorf("message layer.bridge.MsgClaimDepositResponse does not contain field %s", descriptor.FullName())) + panic(fmt.Errorf("message layer.bridge.MsgClaimDepositsResponse does not contain field %s", descriptor.FullName())) } } @@ -2493,13 +2757,13 @@ func (x *fastReflection_MsgClaimDepositResponse) Get(descriptor protoreflect.Fie // empty, read-only value, then it panics. // // Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgClaimDepositResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { +func (x *fastReflection_MsgClaimDepositsResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { switch fd.FullName() { default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: layer.bridge.MsgClaimDepositResponse")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: layer.bridge.MsgClaimDepositsResponse")) } - panic(fmt.Errorf("message layer.bridge.MsgClaimDepositResponse does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message layer.bridge.MsgClaimDepositsResponse does not contain field %s", fd.FullName())) } } @@ -2513,36 +2777,36 @@ func (x *fastReflection_MsgClaimDepositResponse) Set(fd protoreflect.FieldDescri // It panics if the field does not contain a composite type. // // Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgClaimDepositResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { +func (x *fastReflection_MsgClaimDepositsResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: layer.bridge.MsgClaimDepositResponse")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: layer.bridge.MsgClaimDepositsResponse")) } - panic(fmt.Errorf("message layer.bridge.MsgClaimDepositResponse does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message layer.bridge.MsgClaimDepositsResponse does not contain field %s", fd.FullName())) } } // NewField returns a new value that is assignable to the field // for the given descriptor. For scalars, this returns the default value. // For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_MsgClaimDepositResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { +func (x *fastReflection_MsgClaimDepositsResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: layer.bridge.MsgClaimDepositResponse")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: layer.bridge.MsgClaimDepositsResponse")) } - panic(fmt.Errorf("message layer.bridge.MsgClaimDepositResponse does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message layer.bridge.MsgClaimDepositsResponse does not contain field %s", fd.FullName())) } } // WhichOneof reports which field within the oneof is populated, // returning nil if none are populated. // It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_MsgClaimDepositResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { +func (x *fastReflection_MsgClaimDepositsResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { switch d.FullName() { default: - panic(fmt.Errorf("%s is not a oneof field in layer.bridge.MsgClaimDepositResponse", d.FullName())) + panic(fmt.Errorf("%s is not a oneof field in layer.bridge.MsgClaimDepositsResponse", d.FullName())) } panic("unreachable") } @@ -2550,7 +2814,7 @@ func (x *fastReflection_MsgClaimDepositResponse) WhichOneof(d protoreflect.Oneof // GetUnknown retrieves the entire list of unknown fields. // The caller may only mutate the contents of the RawFields // if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_MsgClaimDepositResponse) GetUnknown() protoreflect.RawFields { +func (x *fastReflection_MsgClaimDepositsResponse) GetUnknown() protoreflect.RawFields { return x.unknownFields } @@ -2561,7 +2825,7 @@ func (x *fastReflection_MsgClaimDepositResponse) GetUnknown() protoreflect.RawFi // An empty RawFields may be passed to clear the fields. // // SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgClaimDepositResponse) SetUnknown(fields protoreflect.RawFields) { +func (x *fastReflection_MsgClaimDepositsResponse) SetUnknown(fields protoreflect.RawFields) { x.unknownFields = fields } @@ -2573,7 +2837,7 @@ func (x *fastReflection_MsgClaimDepositResponse) SetUnknown(fields protoreflect. // message type, but the details are implementation dependent. // Validity is not part of the protobuf data model, and may not // be preserved in marshaling or other operations. -func (x *fastReflection_MsgClaimDepositResponse) IsValid() bool { +func (x *fastReflection_MsgClaimDepositsResponse) IsValid() bool { return x != nil } @@ -2583,9 +2847,9 @@ func (x *fastReflection_MsgClaimDepositResponse) IsValid() bool { // The returned methods type is identical to // "google.golang.org/protobuf/runtime/protoiface".Methods. // Consult the protoiface package documentation for details. -func (x *fastReflection_MsgClaimDepositResponse) ProtoMethods() *protoiface.Methods { +func (x *fastReflection_MsgClaimDepositsResponse) ProtoMethods() *protoiface.Methods { size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*MsgClaimDepositResponse) + x := input.Message.Interface().(*MsgClaimDepositsResponse) if x == nil { return protoiface.SizeOutput{ NoUnkeyedLiterals: input.NoUnkeyedLiterals, @@ -2607,7 +2871,7 @@ func (x *fastReflection_MsgClaimDepositResponse) ProtoMethods() *protoiface.Meth } marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*MsgClaimDepositResponse) + x := input.Message.Interface().(*MsgClaimDepositsResponse) if x == nil { return protoiface.MarshalOutput{ NoUnkeyedLiterals: input.NoUnkeyedLiterals, @@ -2637,7 +2901,7 @@ func (x *fastReflection_MsgClaimDepositResponse) ProtoMethods() *protoiface.Meth }, nil } unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*MsgClaimDepositResponse) + x := input.Message.Interface().(*MsgClaimDepositsResponse) if x == nil { return protoiface.UnmarshalOutput{ NoUnkeyedLiterals: input.NoUnkeyedLiterals, @@ -2669,10 +2933,10 @@ func (x *fastReflection_MsgClaimDepositResponse) ProtoMethods() *protoiface.Meth fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgClaimDepositResponse: wiretype end group for non-group") + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgClaimDepositsResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgClaimDepositResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgClaimDepositsResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -2877,18 +3141,18 @@ func (*MsgWithdrawTokensResponse) Descriptor() ([]byte, []int) { return file_layer_bridge_tx_proto_rawDescGZIP(), []int{3} } -type MsgClaimDepositRequest struct { +type MsgClaimDepositsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty"` - DepositId uint64 `protobuf:"varint,2,opt,name=deposit_id,json=depositId,proto3" json:"deposit_id,omitempty"` - Index uint64 `protobuf:"varint,3,opt,name=index,proto3" json:"index,omitempty"` + Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty"` + DepositIds []uint64 `protobuf:"varint,2,rep,packed,name=deposit_ids,json=depositIds,proto3" json:"deposit_ids,omitempty"` + Indices []uint64 `protobuf:"varint,3,rep,packed,name=indices,proto3" json:"indices,omitempty"` } -func (x *MsgClaimDepositRequest) Reset() { - *x = MsgClaimDepositRequest{} +func (x *MsgClaimDepositsRequest) Reset() { + *x = MsgClaimDepositsRequest{} if protoimpl.UnsafeEnabled { mi := &file_layer_bridge_tx_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2896,46 +3160,46 @@ func (x *MsgClaimDepositRequest) Reset() { } } -func (x *MsgClaimDepositRequest) String() string { +func (x *MsgClaimDepositsRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*MsgClaimDepositRequest) ProtoMessage() {} +func (*MsgClaimDepositsRequest) ProtoMessage() {} -// Deprecated: Use MsgClaimDepositRequest.ProtoReflect.Descriptor instead. -func (*MsgClaimDepositRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use MsgClaimDepositsRequest.ProtoReflect.Descriptor instead. +func (*MsgClaimDepositsRequest) Descriptor() ([]byte, []int) { return file_layer_bridge_tx_proto_rawDescGZIP(), []int{4} } -func (x *MsgClaimDepositRequest) GetCreator() string { +func (x *MsgClaimDepositsRequest) GetCreator() string { if x != nil { return x.Creator } return "" } -func (x *MsgClaimDepositRequest) GetDepositId() uint64 { +func (x *MsgClaimDepositsRequest) GetDepositIds() []uint64 { if x != nil { - return x.DepositId + return x.DepositIds } - return 0 + return nil } -func (x *MsgClaimDepositRequest) GetIndex() uint64 { +func (x *MsgClaimDepositsRequest) GetIndices() []uint64 { if x != nil { - return x.Index + return x.Indices } - return 0 + return nil } -type MsgClaimDepositResponse struct { +type MsgClaimDepositsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields } -func (x *MsgClaimDepositResponse) Reset() { - *x = MsgClaimDepositResponse{} +func (x *MsgClaimDepositsResponse) Reset() { + *x = MsgClaimDepositsResponse{} if protoimpl.UnsafeEnabled { mi := &file_layer_bridge_tx_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2943,14 +3207,14 @@ func (x *MsgClaimDepositResponse) Reset() { } } -func (x *MsgClaimDepositResponse) String() string { +func (x *MsgClaimDepositsResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*MsgClaimDepositResponse) ProtoMessage() {} +func (*MsgClaimDepositsResponse) ProtoMessage() {} -// Deprecated: Use MsgClaimDepositResponse.ProtoReflect.Descriptor instead. -func (*MsgClaimDepositResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use MsgClaimDepositsResponse.ProtoReflect.Descriptor instead. +func (*MsgClaimDepositsResponse) Descriptor() ([]byte, []int) { return file_layer_bridge_tx_proto_rawDescGZIP(), []int{5} } @@ -2985,45 +3249,46 @@ var file_layer_bridge_tx_proto_rawDesc = []byte{ 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x0c, 0x82, 0xe7, 0xb0, 0x2a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x22, 0x1b, 0x0a, 0x19, 0x4d, 0x73, 0x67, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x75, 0x0a, 0x16, 0x4d, 0x73, 0x67, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x44, - 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, - 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x64, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3a, 0x0c, 0x82, 0xe7, - 0xb0, 0x2a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x22, 0x19, 0x0a, 0x17, 0x4d, 0x73, - 0x67, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xb0, 0x02, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x69, 0x0a, - 0x13, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x24, 0x2e, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2e, 0x62, 0x72, 0x69, - 0x64, 0x67, 0x65, 0x2e, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x41, 0x74, - 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x2c, 0x2e, 0x6c, 0x61, 0x79, - 0x65, 0x72, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5a, 0x0a, 0x0e, 0x57, 0x69, 0x74, 0x68, - 0x64, 0x72, 0x61, 0x77, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x1f, 0x2e, 0x6c, 0x61, 0x79, - 0x65, 0x72, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x4d, 0x73, 0x67, 0x57, 0x69, 0x74, - 0x68, 0x64, 0x72, 0x61, 0x77, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x1a, 0x27, 0x2e, 0x6c, 0x61, - 0x79, 0x65, 0x72, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x4d, 0x73, 0x67, 0x57, 0x69, - 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5b, 0x0a, 0x0c, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x44, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x12, 0x24, 0x2e, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2e, 0x62, 0x72, 0x69, + 0x6e, 0x73, 0x65, 0x22, 0x7c, 0x0a, 0x17, 0x4d, 0x73, 0x67, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x44, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, + 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x04, 0x52, 0x0a, 0x64, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x49, 0x64, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x69, 0x6e, 0x64, + 0x69, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x04, 0x52, 0x07, 0x69, 0x6e, 0x64, 0x69, + 0x63, 0x65, 0x73, 0x3a, 0x0c, 0x82, 0xe7, 0xb0, 0x2a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, + 0x72, 0x22, 0x1a, 0x0a, 0x18, 0x4d, 0x73, 0x67, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x44, 0x65, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xb3, 0x02, + 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x69, 0x0a, 0x13, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x24, 0x2e, 0x6c, + 0x61, 0x79, 0x65, 0x72, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x4d, 0x73, 0x67, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x1a, 0x2c, 0x2e, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, + 0x65, 0x2e, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x41, 0x74, 0x74, 0x65, + 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x5a, 0x0a, 0x0e, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x54, 0x6f, 0x6b, 0x65, + 0x6e, 0x73, 0x12, 0x1f, 0x2e, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, + 0x65, 0x2e, 0x4d, 0x73, 0x67, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x73, 0x1a, 0x27, 0x2e, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2e, 0x62, 0x72, 0x69, 0x64, + 0x67, 0x65, 0x2e, 0x4d, 0x73, 0x67, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5e, 0x0a, 0x0d, + 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x12, 0x25, 0x2e, + 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x4d, 0x73, 0x67, + 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x44, 0x65, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x6c, 0x61, 0x79, - 0x65, 0x72, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x6c, 0x61, - 0x69, 0x6d, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x1a, 0x05, 0x80, 0xe7, 0xb0, 0x2a, 0x01, 0x42, 0x99, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, - 0x2e, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x42, 0x07, 0x54, - 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x65, 0x6c, 0x6c, 0x6f, 0x72, 0x2d, 0x69, 0x6f, 0x2f, 0x6c, - 0x61, 0x79, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x62, - 0x72, 0x69, 0x64, 0x67, 0x65, 0xa2, 0x02, 0x03, 0x4c, 0x42, 0x58, 0xaa, 0x02, 0x0c, 0x4c, 0x61, - 0x79, 0x65, 0x72, 0x2e, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0xca, 0x02, 0x0c, 0x4c, 0x61, 0x79, - 0x65, 0x72, 0x5c, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0xe2, 0x02, 0x18, 0x4c, 0x61, 0x79, 0x65, - 0x72, 0x5c, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0d, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x3a, 0x3a, 0x42, 0x72, - 0x69, 0x64, 0x67, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x05, 0x80, 0xe7, + 0xb0, 0x2a, 0x01, 0x42, 0x99, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x6c, 0x61, 0x79, 0x65, + 0x72, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x42, 0x07, 0x54, 0x78, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x50, 0x01, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x74, 0x65, 0x6c, 0x6c, 0x6f, 0x72, 0x2d, 0x69, 0x6f, 0x2f, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, + 0xa2, 0x02, 0x03, 0x4c, 0x42, 0x58, 0xaa, 0x02, 0x0c, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x2e, 0x42, + 0x72, 0x69, 0x64, 0x67, 0x65, 0xca, 0x02, 0x0c, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x5c, 0x42, 0x72, + 0x69, 0x64, 0x67, 0x65, 0xe2, 0x02, 0x18, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x5c, 0x42, 0x72, 0x69, + 0x64, 0x67, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, + 0x02, 0x0d, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x3a, 0x3a, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3044,18 +3309,18 @@ var file_layer_bridge_tx_proto_goTypes = []interface{}{ (*MsgRequestAttestationsResponse)(nil), // 1: layer.bridge.MsgRequestAttestationsResponse (*MsgWithdrawTokens)(nil), // 2: layer.bridge.MsgWithdrawTokens (*MsgWithdrawTokensResponse)(nil), // 3: layer.bridge.MsgWithdrawTokensResponse - (*MsgClaimDepositRequest)(nil), // 4: layer.bridge.MsgClaimDepositRequest - (*MsgClaimDepositResponse)(nil), // 5: layer.bridge.MsgClaimDepositResponse + (*MsgClaimDepositsRequest)(nil), // 4: layer.bridge.MsgClaimDepositsRequest + (*MsgClaimDepositsResponse)(nil), // 5: layer.bridge.MsgClaimDepositsResponse (*v1beta1.Coin)(nil), // 6: cosmos.base.v1beta1.Coin } var file_layer_bridge_tx_proto_depIdxs = []int32{ 6, // 0: layer.bridge.MsgWithdrawTokens.amount:type_name -> cosmos.base.v1beta1.Coin 0, // 1: layer.bridge.Msg.RequestAttestations:input_type -> layer.bridge.MsgRequestAttestations 2, // 2: layer.bridge.Msg.WithdrawTokens:input_type -> layer.bridge.MsgWithdrawTokens - 4, // 3: layer.bridge.Msg.ClaimDeposit:input_type -> layer.bridge.MsgClaimDepositRequest + 4, // 3: layer.bridge.Msg.ClaimDeposits:input_type -> layer.bridge.MsgClaimDepositsRequest 1, // 4: layer.bridge.Msg.RequestAttestations:output_type -> layer.bridge.MsgRequestAttestationsResponse 3, // 5: layer.bridge.Msg.WithdrawTokens:output_type -> layer.bridge.MsgWithdrawTokensResponse - 5, // 6: layer.bridge.Msg.ClaimDeposit:output_type -> layer.bridge.MsgClaimDepositResponse + 5, // 6: layer.bridge.Msg.ClaimDeposits:output_type -> layer.bridge.MsgClaimDepositsResponse 4, // [4:7] is the sub-list for method output_type 1, // [1:4] is the sub-list for method input_type 1, // [1:1] is the sub-list for extension type_name @@ -3118,7 +3383,7 @@ func file_layer_bridge_tx_proto_init() { } } file_layer_bridge_tx_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MsgClaimDepositRequest); i { + switch v := v.(*MsgClaimDepositsRequest); i { case 0: return &v.state case 1: @@ -3130,7 +3395,7 @@ func file_layer_bridge_tx_proto_init() { } } file_layer_bridge_tx_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MsgClaimDepositResponse); i { + switch v := v.(*MsgClaimDepositsResponse); i { case 0: return &v.state case 1: diff --git a/api/layer/bridge/tx_grpc.pb.go b/api/layer/bridge/tx_grpc.pb.go index 89d75be81..91160a975 100644 --- a/api/layer/bridge/tx_grpc.pb.go +++ b/api/layer/bridge/tx_grpc.pb.go @@ -20,7 +20,7 @@ const _ = grpc.SupportPackageIsVersion7 type MsgClient interface { RequestAttestations(ctx context.Context, in *MsgRequestAttestations, opts ...grpc.CallOption) (*MsgRequestAttestationsResponse, error) WithdrawTokens(ctx context.Context, in *MsgWithdrawTokens, opts ...grpc.CallOption) (*MsgWithdrawTokensResponse, error) - ClaimDeposit(ctx context.Context, in *MsgClaimDepositRequest, opts ...grpc.CallOption) (*MsgClaimDepositResponse, error) + ClaimDeposits(ctx context.Context, in *MsgClaimDepositsRequest, opts ...grpc.CallOption) (*MsgClaimDepositsResponse, error) } type msgClient struct { @@ -49,9 +49,9 @@ func (c *msgClient) WithdrawTokens(ctx context.Context, in *MsgWithdrawTokens, o return out, nil } -func (c *msgClient) ClaimDeposit(ctx context.Context, in *MsgClaimDepositRequest, opts ...grpc.CallOption) (*MsgClaimDepositResponse, error) { - out := new(MsgClaimDepositResponse) - err := c.cc.Invoke(ctx, "/layer.bridge.Msg/ClaimDeposit", in, out, opts...) +func (c *msgClient) ClaimDeposits(ctx context.Context, in *MsgClaimDepositsRequest, opts ...grpc.CallOption) (*MsgClaimDepositsResponse, error) { + out := new(MsgClaimDepositsResponse) + err := c.cc.Invoke(ctx, "/layer.bridge.Msg/ClaimDeposits", in, out, opts...) if err != nil { return nil, err } @@ -64,7 +64,7 @@ func (c *msgClient) ClaimDeposit(ctx context.Context, in *MsgClaimDepositRequest type MsgServer interface { RequestAttestations(context.Context, *MsgRequestAttestations) (*MsgRequestAttestationsResponse, error) WithdrawTokens(context.Context, *MsgWithdrawTokens) (*MsgWithdrawTokensResponse, error) - ClaimDeposit(context.Context, *MsgClaimDepositRequest) (*MsgClaimDepositResponse, error) + ClaimDeposits(context.Context, *MsgClaimDepositsRequest) (*MsgClaimDepositsResponse, error) mustEmbedUnimplementedMsgServer() } @@ -78,8 +78,8 @@ func (UnimplementedMsgServer) RequestAttestations(context.Context, *MsgRequestAt func (UnimplementedMsgServer) WithdrawTokens(context.Context, *MsgWithdrawTokens) (*MsgWithdrawTokensResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method WithdrawTokens not implemented") } -func (UnimplementedMsgServer) ClaimDeposit(context.Context, *MsgClaimDepositRequest) (*MsgClaimDepositResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ClaimDeposit not implemented") +func (UnimplementedMsgServer) ClaimDeposits(context.Context, *MsgClaimDepositsRequest) (*MsgClaimDepositsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ClaimDeposits not implemented") } func (UnimplementedMsgServer) mustEmbedUnimplementedMsgServer() {} @@ -130,20 +130,20 @@ func _Msg_WithdrawTokens_Handler(srv interface{}, ctx context.Context, dec func( return interceptor(ctx, in, info, handler) } -func _Msg_ClaimDeposit_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MsgClaimDepositRequest) +func _Msg_ClaimDeposits_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgClaimDepositsRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(MsgServer).ClaimDeposit(ctx, in) + return srv.(MsgServer).ClaimDeposits(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/layer.bridge.Msg/ClaimDeposit", + FullMethod: "/layer.bridge.Msg/ClaimDeposits", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MsgServer).ClaimDeposit(ctx, req.(*MsgClaimDepositRequest)) + return srv.(MsgServer).ClaimDeposits(ctx, req.(*MsgClaimDepositsRequest)) } return interceptor(ctx, in, info, handler) } @@ -164,8 +164,8 @@ var Msg_ServiceDesc = grpc.ServiceDesc{ Handler: _Msg_WithdrawTokens_Handler, }, { - MethodName: "ClaimDeposit", - Handler: _Msg_ClaimDeposit_Handler, + MethodName: "ClaimDeposits", + Handler: _Msg_ClaimDeposits_Handler, }, }, Streams: []grpc.StreamDesc{}, diff --git a/app/app.go b/app/app.go index ae661442f..df7f8ff40 100644 --- a/app/app.go +++ b/app/app.go @@ -993,7 +993,7 @@ func (app *App) preBlocker(ph *ProposalHandler) func(sdk.Context, *abci.RequestF } func (app *App) RegisterUpgradeHandlers() { - const UpgradeName = "v0.5.0" + const UpgradeName = "v0.6.1" app.UpgradeKeeper.SetUpgradeHandler( UpgradeName, diff --git a/app/extend_vote_test.go b/app/extend_vote_test.go index 51ecf0e5a..3fd9cfdc4 100644 --- a/app/extend_vote_test.go +++ b/app/extend_vote_test.go @@ -3,7 +3,7 @@ package app_test import ( "encoding/json" "errors" - "fmt" + "reflect" "testing" "github.com/agiledragon/gomonkey/v2" @@ -17,11 +17,13 @@ import ( "github.com/tellor-io/layer/testutil/sample" bridgetypes "github.com/tellor-io/layer/x/bridge/types" + "cosmossdk.io/api/cosmos/crypto/secp256k1" "cosmossdk.io/collections" "cosmossdk.io/log" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/crypto/hd" "github.com/cosmos/cosmos-sdk/crypto/keyring" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -33,17 +35,13 @@ type VoteExtensionTestSuite struct { oracleKeeper *mocks.OracleKeeper bridgeKeeper *mocks.BridgeKeeper stakingKeeper *mocks.StakingKeeper - kr keyring.Keyring - tempDir string + kr *mocks.Keyring cdc codec.Codec } func (s *VoteExtensionTestSuite) SetupTest() { - require := s.Require() - registry := codectypes.NewInterfaceRegistry() - cdc := codec.NewProtoCodec(registry) - s.cdc = cdc + s.cdc = codec.NewProtoCodec(registry) s.oracleKeeper = mocks.NewOracleKeeper(s.T()) s.bridgeKeeper = mocks.NewBridgeKeeper(s.T()) s.stakingKeeper = mocks.NewStakingKeeper(s.T()) @@ -52,31 +50,17 @@ func (s *VoteExtensionTestSuite) SetupTest() { s.ctx = testutils.CreateTestContext(s.T()) s.handler = app.NewVoteExtHandler( log.NewNopLogger(), - cdc, + s.cdc, s.oracleKeeper, s.bridgeKeeper, ) +} - // create new keyring in - s.tempDir = s.T().TempDir() - viper.Set("keyring-backend", "test") - viper.Set("keyring-dir", s.tempDir) - var err error - s.kr, err = s.handler.InitKeyring() - require.NoError(err) - require.NotNil(s.kr) - - // backend := "test" - // tempDir := s.T().TempDir() - // keyring, err := keyring.New("TestExport", backend, tempDir, nil, cdc) - // fmt.Println("keyring: ", keyring) - // fmt.Println("temp dir: ", tempDir) - // s.kr = keyring - // require.NoError(err) - - // keys, err := s.kr.List() - // require.NoError(err) - // fmt.Println("Keys in keyring: ", keys) +func (s *VoteExtensionTestSuite) TearDownTest() { + s.oracleKeeper.AssertExpectations(s.T()) + s.bridgeKeeper.AssertExpectations(s.T()) + s.stakingKeeper.AssertExpectations(s.T()) + viper.Reset() } func TestVoteExtensionTestSuite(t *testing.T) { @@ -140,6 +124,12 @@ func (s *VoteExtensionTestSuite) TestVerifyVoteExtHandler() { require.NoError(err) require.Equal(res.Status, abci.ResponseVerifyVoteExtension_REJECT) + // no err unmarshalling, no err from GetAttestationRequestsByHeight, voteExt oracle att length > length request, reject + bk.On("GetAttestationRequestsByHeight", s.ctx, uint64(2)).Return(nil, collections.ErrNotFound).Once() + res, err = h.VerifyVoteExtensionHandler(s.ctx, req) + require.NoError(err) + require.Equal(res.Status, abci.ResponseVerifyVoteExtension_REJECT) + // no err unmarshalling, no err from GetAttestationRequestsByHeight, voteExt oracle att length > length request, reject attReq := bridgetypes.AttestationRequests{ Requests: []*bridgetypes.AttestationRequest{ @@ -190,12 +180,26 @@ func (s *VoteExtensionTestSuite) TestVerifyVoteExtHandler() { VoteExtension: bridgeVoteExtBz, } bk.On("GetAttestationRequestsByHeight", s.ctx, uint64(2)).Return(&attReq, nil).Once() + bridgeVoteExt.OracleAttestations = append(bridgeVoteExt.OracleAttestations, app.OracleAttestation{ + Attestation: []byte("attestation2"), + Snapshot: []byte("snapshot2"), + }) + require.Equal(len(bridgeVoteExt.OracleAttestations), 2) + bridgeVoteExtBz, err = json.Marshal(bridgeVoteExt) + require.NoError(err) + req = &abci.RequestVerifyVoteExtension{ + VoteExtension: bridgeVoteExtBz, + } + bk.On("GetAttestationRequestsByHeight", s.ctx, uint64(2)).Return(&attReq, nil).Once() res, err = h.VerifyVoteExtensionHandler(s.ctx, req) require.NoError(err) require.Equal(res.Status, abci.ResponseVerifyVoteExtension_REJECT) - // no errs unmarshalling, no err from GetAttestationRequestsByHeight, voteExt oracle att length == length request, initial sig good, valset sig good, accept - bridgeVoteExt.ValsetSignature.Signature = []byte("signature") + // no err unmarshalling, no err from GetAttestationRequestsByHeight, voteExt oracle att length == length request, initial sig too big, reject + bridgeVoteExt.InitialSignature.SignatureA = make([]byte, 100000) + bridgeVoteExt.OracleAttestations = []app.OracleAttestation{ + oracleAtt, + } bridgeVoteExtBz, err = json.Marshal(bridgeVoteExt) require.NoError(err) req = &abci.RequestVerifyVoteExtension{ @@ -204,120 +208,39 @@ func (s *VoteExtensionTestSuite) TestVerifyVoteExtHandler() { bk.On("GetAttestationRequestsByHeight", s.ctx, uint64(2)).Return(&attReq, nil).Once() res, err = h.VerifyVoteExtensionHandler(s.ctx, req) require.NoError(err) - require.Equal(res.Status, abci.ResponseVerifyVoteExtension_ACCEPT) -} - -// create a keyring in the test, sotre in temp directort, modify voteexthandler -// or read youre own computer -// maybe even pass in a keyring instead of reading it - -func (s *VoteExtensionTestSuite) TestSignMessage() { - require := s.Require() - h := s.handler + require.Equal(res.Status, abci.ResponseVerifyVoteExtension_REJECT) - // Initial keyring state - keys, err := s.kr.List() + // no err unmarshalling, no err from GetAttestationRequestsByHeight, voteExt oracle att length == length request, initial sig good, valset sig too big, reject + bridgeVoteExt.ValsetSignature.Signature = make([]byte, 100000) + bridgeVoteExt.InitialSignature = app.InitialSignature{ + SignatureA: []byte("signature"), + SignatureB: []byte("signature"), + } + bridgeVoteExtBz, err = json.Marshal(bridgeVoteExt) require.NoError(err) - fmt.Println("Initial keys in keyring: ", keys) - - res, err := h.SignMessage([]byte("msg")) - require.Error(err) - require.Nil(res) - - // create key - // cmd := exec.Command("layerd", "keys", "add", "key0", "--keyring-backend", "test", "--keyring-dir", s.tempDir) - // output, err := cmd.CombinedOutput() - // require.NoError(err) - // require.NotNil(output) - // fmt.Println(string(output)) - - // cmd = exec.Command("layerd", "keys", "list", "--keyring-backend", "test", "--keyring-dir", s.tempDir) - // output, err = cmd.CombinedOutput() - // require.NoError(err) - // require.NotNil(output) - // fmt.Println(string(output)) - - // Log the keyring state after adding the key - // keys, err = s.kr.List() - // require.NoError(err) - // fmt.Println("Keys in keyring after adding key: ", keys) - - // viper.Set("key-name", "key0") - // res, err = h.SignMessage([]byte("msg")) - // require.NoError(err) - // require.NotNil(res) - - // kr := s.kr - // uid := "testOne" - // // encryptPassphrase := "this passphrase has been used for all test vectors" - // // armor := "-----BEGIN TENDERMINT PRIVATE KEY-----\nkdf: bcrypt\nsalt: 6BC5D5187F9DF241E1A1243EECFF9C17\ntype: secp256k1\n\nGDPpPfrSVZloiwufbal19fmd75QeiqwToZ949SwmnxxM03qL75xXVf3tTD/BrF4l\nFs14HuhwntDBM2xgZvymTBk2edHlEI20Phv6oC0=\n=/zZh\n-----END TENDERMINT PRIVATE KEY-----" - // // err := kr.ImportPrivKey(uid, armor, encryptPassphrase) - // // require.NoError(err) - // record, mn, err := kr.NewMnemonic(uid, keyring.English, sdk.FullFundraiserPath, "", hd.Secp256k1) - // require.NoError(err) - // require.NotNil(mn) - // require.NotNil(record) - // record2, err := kr.NewAccount(uid, mn, "", "", hd.Secp256k1) - // require.NoError(err) - // require.NotNil(record2) - - // // List keys after adding - // keys, err := kr.List() - // require.NoError(err) - // fmt.Println("Keys in keyring after cmd: ", keys) - // s.T().TempDir() - - // Create a temporary directory for the keyring - // tempDir, err := os.MkdirTemp("", "keyring-test") - // require.NoError(err) - // defer os.RemoveAll(tempDir) - - // viper.Set("keyring-backend", "test") - // viper.Set("keyring-dir", tempDir) - // viper.Set("key-name", "key5") - - // kr, err := s.handler.InitKeyring() - // require.NoError(err) - // require.NotNil(kr) - // fmt.Println("Initialized keyring: ", kr) - - // // Add key using command - // cmd := exec.Command("layerd", "keys", "add", "key5", "--keyring-dir", tempDir) - // output, err := cmd.CombinedOutput() - // require.NoError(err) - // require.NotNil(output) - // fmt.Println("Output from adding key: ", string(output)) - - // // List keys after adding - // keys, err := kr.List() - // require.NoError(err) - // require.NotNil(keys) - // fmt.Println("Keys in keyring: ", keys) -} - -func (s *VoteExtensionTestSuite) TestGetKeyring() { - require := s.Require() - h := s.handler - - kr, err := h.GetKeyring() + req = &abci.RequestVerifyVoteExtension{ + VoteExtension: bridgeVoteExtBz, + } + bk.On("GetAttestationRequestsByHeight", s.ctx, uint64(2)).Return(&attReq, nil).Once() + res, err = h.VerifyVoteExtensionHandler(s.ctx, req) require.NoError(err) - require.NotNil(kr) -} - -func (s *VoteExtensionTestSuite) TestGetOperatorAddress() { - // require := s.Require() - // h := s.handler - // kr := s.kr + require.Equal(res.Status, abci.ResponseVerifyVoteExtension_REJECT) - // viper.Set("key-name", "key20") + // no errs unmarshalling, no err from GetAttestationRequestsByHeight, voteExt oracle att length == length request, initial sig good, valset sig good, accept + bridgeVoteExt.ValsetSignature.Signature = []byte("signature") + bridgeVoteExtBz, err = json.Marshal(bridgeVoteExt) + require.NoError(err) + req = &abci.RequestVerifyVoteExtension{ + VoteExtension: bridgeVoteExtBz, + } + // bk.On("GetAttestationRequestsByHeight", s.ctx, uint64(2)).Return(&attReq, nil).Once() + res, err = h.VerifyVoteExtensionHandler(s.ctx, req) + require.NoError(err) + require.Equal(res.Status, abci.ResponseVerifyVoteExtension_ACCEPT) - // addr, err := h.GetOperatorAddress() - // require.NoError(err) - // require.NotNil(addr) + // s.TearDownTest() } -// use test case struct - func (s *VoteExtensionTestSuite) TestExtendVoteHandler() { require := s.Require() h := s.handler @@ -328,7 +251,6 @@ func (s *VoteExtensionTestSuite) TestExtendVoteHandler() { type testCase struct { name string setupMocks func() - request *abci.RequestExtendVote expectedError error validateResponse func(*abci.ResponseExtendVote) } @@ -337,7 +259,6 @@ func (s *VoteExtensionTestSuite) TestExtendVoteHandler() { { name: "GetOperatorAddress error", setupMocks: func() {}, - request: &abci.RequestExtendVote{}, expectedError: nil, validateResponse: func(resp *abci.ResponseExtendVote) { require.NotNil(resp) @@ -347,7 +268,7 @@ func (s *VoteExtensionTestSuite) TestExtendVoteHandler() { name: "err on SignInitialMessage", setupMocks: func() { oppAddr := sample.AccAddress() - patches.ApplyMethod(h, "GetOperatorAddress", func(_ *app.VoteExtHandler) (string, error) { + patches.ApplyMethod(reflect.TypeOf(h), "GetOperatorAddress", func(_ *app.VoteExtHandler) (string, error) { return oppAddr, nil }) bk.On("GetEVMAddressByOperator", ctx, oppAddr).Return(nil, collections.ErrNotFound).Once() @@ -361,10 +282,10 @@ func (s *VoteExtensionTestSuite) TestExtendVoteHandler() { name: "err on GetAttestationRequestsByHeight", setupMocks: func() { oppAddr := sample.AccAddress() - patches.ApplyMethod(h, "GetOperatorAddress", func(_ *app.VoteExtHandler) (string, error) { + patches.ApplyMethod(reflect.TypeOf(h), "GetOperatorAddress", func(_ *app.VoteExtHandler) (string, error) { return oppAddr, nil }) - patches.ApplyMethod(h, "SignInitialMessage", func(_ *app.VoteExtHandler) ([]byte, []byte, error) { + patches.ApplyMethod(reflect.TypeOf(h), "SignInitialMessage", func(_ *app.VoteExtHandler) ([]byte, []byte, error) { return []byte("signatureA"), []byte("signatureB"), nil }) bk.On("GetEVMAddressByOperator", ctx, oppAddr).Return(nil, collections.ErrNotFound).Once() @@ -380,7 +301,7 @@ func (s *VoteExtensionTestSuite) TestExtendVoteHandler() { setupMocks: func() { oppAddr := sample.AccAddress() evmAddr := common.BytesToAddress([]byte("evmAddr")) - patches.ApplyMethod(h, "GetOperatorAddress", func(_ *app.VoteExtHandler) (string, error) { + patches.ApplyMethod(reflect.TypeOf(h), "GetOperatorAddress", func(_ *app.VoteExtHandler) (string, error) { return oppAddr, nil }) bk.On("GetEVMAddressByOperator", ctx, oppAddr).Return(evmAddr.Bytes(), nil).Once() @@ -392,7 +313,7 @@ func (s *VoteExtensionTestSuite) TestExtendVoteHandler() { }, } bk.On("GetAttestationRequestsByHeight", ctx, uint64(2)).Return(&attReq, nil).Once() - patches.ApplyMethod(h, "SignMessage", func(_ *app.VoteExtHandler, msg []byte) ([]byte, error) { + patches.ApplyMethod(reflect.TypeOf(h), "SignMessage", func(_ *app.VoteExtHandler, msg []byte) ([]byte, error) { return []byte("signedMsg"), nil }) bk.On("GetLatestCheckpointIndex", ctx).Return(uint64(0), errors.New("error")).Once() @@ -407,7 +328,7 @@ func (s *VoteExtensionTestSuite) TestExtendVoteHandler() { setupMocks: func() { oppAddr := sample.AccAddress() evmAddr := common.BytesToAddress([]byte("evmAddr")) - patches.ApplyMethod(h, "GetOperatorAddress", func(_ *app.VoteExtHandler) (string, error) { + patches.ApplyMethod(reflect.TypeOf(h), "GetOperatorAddress", func(_ *app.VoteExtHandler) (string, error) { return oppAddr, nil }) bk.On("GetEVMAddressByOperator", ctx, oppAddr).Return(evmAddr.Bytes(), nil).Once() @@ -419,7 +340,7 @@ func (s *VoteExtensionTestSuite) TestExtendVoteHandler() { }, } bk.On("GetAttestationRequestsByHeight", ctx, uint64(2)).Return(&attReq, nil).Once() - patches.ApplyMethod(h, "SignMessage", func(_ *app.VoteExtHandler, msg []byte) ([]byte, error) { + patches.ApplyMethod(reflect.TypeOf(h), "SignMessage", func(_ *app.VoteExtHandler, msg []byte) ([]byte, error) { return []byte("signedMsg"), nil }) bk.On("GetLatestCheckpointIndex", ctx).Return(uint64(1), nil).Once() @@ -428,7 +349,7 @@ func (s *VoteExtensionTestSuite) TestExtendVoteHandler() { } bk.On("GetValidatorTimestampByIdxFromStorage", ctx, uint64(1)).Return(checkpointTimestamp, nil).Once() bk.On("GetValidatorDidSignCheckpoint", ctx, oppAddr, uint64(1)).Return(true, int64(1), nil).Once() - patches.ApplyMethod(h, "EncodeAndSignMessage", func(_ *app.VoteExtHandler, checkpoint string) ([]byte, error) { + patches.ApplyMethod(reflect.TypeOf(h), "EncodeAndSignMessage", func(_ *app.VoteExtHandler, checkpoint string) ([]byte, error) { return []byte("signedCheckpoint"), nil }) }, @@ -441,6 +362,7 @@ func (s *VoteExtensionTestSuite) TestExtendVoteHandler() { for _, tc := range testCases { s.Run(tc.name, func() { + defer patches.Reset() tc.setupMocks() req := &abci.RequestExtendVote{} resp, err := h.ExtendVoteHandler(ctx, req) @@ -451,7 +373,407 @@ func (s *VoteExtensionTestSuite) TestExtendVoteHandler() { require.NoError(err) } tc.validateResponse(resp) + s.TearDownTest() + }) + } +} + +func (s *VoteExtensionTestSuite) TestGetKeyring() { + require := s.Require() + h := s.handler + + viper.Set("keyring-backend", "test") + viper.Set("keyring-dir", s.T().TempDir()) + kr, err := h.GetKeyring() + require.NoError(err) + require.NotNil(kr) + + s.TearDownTest() +} + +func (s *VoteExtensionTestSuite) TestGetOperatorAddress() { + require := s.Require() + // h := s.handler + patches := gomonkey.NewPatches() + + type testCase struct { + name string + setupMocks func(h *app.VoteExtHandler) *gomonkey.Patches + expectedError bool + expectedErrorMsg string + } + + testCases := []testCase{ + { + name: "err getting keyring", + setupMocks: func(h *app.VoteExtHandler) *gomonkey.Patches { + s.kr = nil + return nil + }, + expectedError: true, + expectedErrorMsg: "failed to get keyring:", + }, + { + name: "err getting keyname", + setupMocks: func(h *app.VoteExtHandler) *gomonkey.Patches { + s.kr = mocks.NewKeyring(s.T()) + tempDir := s.T().TempDir() + viper.Set("keyring-backend", "test") + viper.Set("keyring-dir", tempDir) + return patches + }, + expectedError: true, + expectedErrorMsg: "key name not found, please set --key-name flag", + }, + { + name: "empty keyring", + setupMocks: func(h *app.VoteExtHandler) *gomonkey.Patches { + tempDir := s.T().TempDir() + viper.Set("key-name", "testkey") + viper.Set("keyring-backend", "test") + viper.Set("keyring-dir", tempDir) + mockKr := mocks.NewKeyring(s.T()) + mockKr.On("List").Return([]*keyring.Record{}, nil).Once() + + patches := gomonkey.ApplyMethod(reflect.TypeOf(h), "GetKeyring", + func(_ *app.VoteExtHandler) (keyring.Keyring, error) { + return mockKr, nil + }) + return patches + }, + expectedError: true, + expectedErrorMsg: "no keys found in keyring", + }, + { + name: "kr.Key error", + setupMocks: func(h *app.VoteExtHandler) *gomonkey.Patches { + tempDir := s.T().TempDir() + viper.Set("keyring-backend", "test") + viper.Set("keyring-dir", tempDir) + viper.Set("key-name", "testkey") + pubKey := &secp256k1.PubKey{Key: []byte("pubkey")} + anyPubKey, err := codectypes.NewAnyWithValue(pubKey) + require.NoError(err) + mockKr := mocks.NewKeyring(s.T()) + mockKr.On("List").Return([]*keyring.Record{ + {Name: "testkey", PubKey: anyPubKey}, + }, nil).Once() + mockKr.On("Key", "testkey").Return(nil, errors.New("error!")).Once() + + patches := gomonkey.ApplyMethod(reflect.TypeOf(h), "GetKeyring", + func(_ *app.VoteExtHandler) (keyring.Keyring, error) { + return mockKr, nil + }) + return patches + }, + expectedError: true, + expectedErrorMsg: "failed to get operator key:", + }, + { + name: "success", + setupMocks: func(h *app.VoteExtHandler) *gomonkey.Patches { + tempDir := s.T().TempDir() + viper.Set("keyring-backend", "test") + viper.Set("keyring-dir", tempDir) + viper.Set("key-name", "testkey") + priv := hd.Secp256k1.Generate()([]byte("test")) + // Create a public key + pubKey := priv.PubKey() + // Create an AnyPubKey + anyPubKey, err := codectypes.NewAnyWithValue(pubKey) + require.NoError(err) + // Create a local item + localItem, err := keyring.NewLocalRecord( + "testkey", + priv, + pubKey, + ) + require.NoError(err) + mockKr := mocks.NewKeyring(s.T()) + mockKr.On("List").Return([]*keyring.Record{ + {Name: "testkey", PubKey: anyPubKey}, + }, nil).Once() + + mockKr.On("Key", "testkey").Return(&keyring.Record{ + Name: "testkey", + PubKey: anyPubKey, + Item: localItem.Item, + }, nil).Once() + patches := gomonkey.ApplyMethod(reflect.TypeOf(h), "GetKeyring", + func(_ *app.VoteExtHandler) (keyring.Keyring, error) { + return mockKr, nil + }) + return patches + }, + expectedError: false, + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + handler := app.NewVoteExtHandler( + log.NewNopLogger(), + s.cdc, + s.oracleKeeper, + s.bridgeKeeper, + ) defer patches.Reset() + defer viper.Reset() + tc.setupMocks(handler) + resp, err := handler.GetOperatorAddress() + if tc.expectedError { + require.Error(err) + require.Contains(err.Error(), tc.expectedErrorMsg) + } else { + require.NoError(err) + require.NotEmpty(resp) + } + s.TearDownTest() + }) + } +} + +func (s *VoteExtensionTestSuite) TestSignInitialMessage() { + require := s.Require() + h := s.handler + + patches := gomonkey.NewPatches() + patches.ApplyMethod(reflect.TypeOf(h), "SignMessage", func(_ *app.VoteExtHandler, msg []byte) ([]byte, error) { + return []byte("signedMsg"), nil + }) + + sigA, sigB, err := h.SignInitialMessage() + require.NoError(err) + require.NotEmpty(sigA) + require.NotEmpty(sigB) + + s.TearDownTest() + patches.Reset() +} + +func (s *VoteExtensionTestSuite) TestCheckAndSignValidatorCheckpoint() { + require := s.Require() + h := s.handler + bk := s.bridgeKeeper + ctx := s.ctx.WithBlockHeight(2) + + testCases := []struct { + name string + setupMocks func(string) + expectedSig []byte + expectedTimestamp uint64 + expectedError error + }{ + { + name: "Validator already signed", + setupMocks: func(oppAddr string) { + bk.On("GetLatestCheckpointIndex", ctx).Return(uint64(1), nil).Once() + bk.On("GetValidatorTimestampByIdxFromStorage", ctx, uint64(1)).Return(bridgetypes.CheckpointTimestamp{ + Timestamp: 10, + }, nil).Once() + bk.On("GetValidatorDidSignCheckpoint", ctx, oppAddr, uint64(10)).Return(true, int64(1), nil).Maybe() + }, + expectedSig: nil, + expectedTimestamp: 0, + expectedError: nil, + }, + { + name: "Error getting latest checkpoint index", + setupMocks: func(oppAddr string) { + bk.On("GetLatestCheckpointIndex", ctx).Return(uint64(0), errors.New("index error")).Once() + }, + expectedSig: nil, + expectedTimestamp: 0, + expectedError: errors.New("index error"), + }, + { + name: "Error getting validator timestamp", + setupMocks: func(oppAddr string) { + bk.On("GetLatestCheckpointIndex", ctx).Return(uint64(1), nil).Once() + bk.On("GetValidatorTimestampByIdxFromStorage", ctx, uint64(1)).Return(bridgetypes.CheckpointTimestamp{}, errors.New("timestamp error")).Once() + }, + expectedSig: nil, + expectedTimestamp: 0, + expectedError: errors.New("timestamp error"), + }, + { + name: "Error checking if validator signed", + setupMocks: func(oppAddr string) { + bk.On("GetLatestCheckpointIndex", ctx).Return(uint64(1), nil).Once() + bk.On("GetValidatorTimestampByIdxFromStorage", ctx, uint64(1)).Return(bridgetypes.CheckpointTimestamp{ + Timestamp: 10, + }, nil).Once() + bk.On("GetValidatorDidSignCheckpoint", ctx, oppAddr, uint64(10)).Return(false, int64(0), errors.New("sign check error")).Once() + }, + expectedSig: nil, + expectedTimestamp: 0, + expectedError: errors.New("sign check error"), + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + oppAddr := sample.AccAddress() + s.mockGetOperatorAddress(oppAddr, nil) + tc.setupMocks(oppAddr) + + sig, timestamp, err := h.CheckAndSignValidatorCheckpoint(ctx) + + if tc.expectedError != nil { + require.Error(err) + require.Contains(err.Error(), tc.expectedError.Error()) + } else { + require.NoError(err) + } + require.Equal(tc.expectedSig, sig) + require.Equal(tc.expectedTimestamp, timestamp) + + s.TearDownTest() + }) + } +} + +func (s *VoteExtensionTestSuite) mockGetOperatorAddress(address string, err error) { + patches := gomonkey.NewPatches() + patches.ApplyMethod(reflect.TypeOf(s.handler), "GetOperatorAddress", func(_ *app.VoteExtHandler) (string, error) { + return address, err + }) + s.T().Cleanup(patches.Reset) +} + +func (s *VoteExtensionTestSuite) TestEncodeAndSignMessage() { + require := s.Require() + h := s.handler + + tests := []struct { + name string + checkpointString string + mockSignature []byte + mockError error + expectedSignature []byte + expectedError string + }{ + { + name: "Valid checkpoint", + checkpointString: "0123456789abcdef", + mockSignature: []byte("mocksignature"), + mockError: nil, + expectedSignature: []byte("mocksignature"), + expectedError: "", + }, + { + name: "Invalid hex string", + checkpointString: "invalid hex", + mockSignature: nil, + mockError: nil, + expectedSignature: nil, + expectedError: "encoding/hex: invalid byte", + }, + { + name: "SignMessage error", + checkpointString: "0123456789abcdef", + mockSignature: nil, + mockError: errors.New("signing error"), + expectedSignature: nil, + expectedError: "signing error", + }, + } + + for _, tt := range tests { + s.Run(tt.name, func() { + // Mock the SignMessage method + patches := gomonkey.ApplyMethod(reflect.TypeOf(h), "SignMessage", + func(_ *app.VoteExtHandler, msg []byte) ([]byte, error) { + return tt.mockSignature, tt.mockError + }) + defer patches.Reset() + + // Call the function + signature, err := h.EncodeAndSignMessage(tt.checkpointString) + + // Assert the results + if tt.expectedError != "" { + require.Error(err) + require.Contains(err.Error(), tt.expectedError) + } else { + require.NoError(err) + } + require.Equal(tt.expectedSignature, signature) + }) + } +} + +func (s *VoteExtensionTestSuite) TestGetValidatorIndexInValset() { + require := s.Require() + h := s.handler + ctx := s.ctx + + testCases := []struct { + name string + evmAddr []byte + valset *bridgetypes.BridgeValidatorSet + expectedIndex int + expectedError error + }{ + { + name: "Validator found at index 0", + evmAddr: []byte("evmAddr1"), + valset: &bridgetypes.BridgeValidatorSet{ + BridgeValidatorSet: []*bridgetypes.BridgeValidator{ + {EthereumAddress: []byte("evmAddr1"), Power: 1}, + {EthereumAddress: []byte("evmAddr2"), Power: 2}, + }, + }, + expectedIndex: 0, + expectedError: nil, + }, + { + name: "Validator found at index 1", + evmAddr: []byte("evmAddr2"), + valset: &bridgetypes.BridgeValidatorSet{ + BridgeValidatorSet: []*bridgetypes.BridgeValidator{ + {EthereumAddress: []byte("evmAddr1"), Power: 1}, + {EthereumAddress: []byte("evmAddr2"), Power: 2}, + }, + }, + expectedIndex: 1, + expectedError: nil, + }, + { + name: "Validator not found", + evmAddr: []byte("evmAddr3"), + valset: &bridgetypes.BridgeValidatorSet{ + BridgeValidatorSet: []*bridgetypes.BridgeValidator{ + {EthereumAddress: []byte("evmAddr1"), Power: 1}, + {EthereumAddress: []byte("evmAddr2"), Power: 2}, + }, + }, + expectedIndex: -1, + expectedError: errors.New("validator not found in valset"), + }, + { + name: "Empty valset", + evmAddr: []byte("evmAddr1"), + valset: &bridgetypes.BridgeValidatorSet{ + BridgeValidatorSet: []*bridgetypes.BridgeValidator{}, + }, + expectedIndex: -1, + expectedError: errors.New("validator not found in valset"), + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + index, err := h.GetValidatorIndexInValset(ctx, tc.evmAddr, tc.valset) + + if tc.expectedError != nil { + require.Error(err) + require.Contains(err.Error(), tc.expectedError.Error()) + } else { + require.NoError(err) + } + + require.Equal(tc.expectedIndex, index) }) } } diff --git a/app/mocks/Keyring.go b/app/mocks/Keyring.go new file mode 100644 index 000000000..9107f01db --- /dev/null +++ b/app/mocks/Keyring.go @@ -0,0 +1,567 @@ +// Code generated by mockery v2.23.1. DO NOT EDIT. + +package mocks + +import ( + keyring "github.com/cosmos/cosmos-sdk/crypto/keyring" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + + mock "github.com/stretchr/testify/mock" + + signing "github.com/cosmos/cosmos-sdk/types/tx/signing" + + types "github.com/cosmos/cosmos-sdk/types" +) + +// Keyring is an autogenerated mock type for the Keyring type +type Keyring struct { + mock.Mock +} + +// Backend provides a mock function with given fields: +func (_m *Keyring) Backend() string { + ret := _m.Called() + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// Delete provides a mock function with given fields: uid +func (_m *Keyring) Delete(uid string) error { + ret := _m.Called(uid) + + var r0 error + if rf, ok := ret.Get(0).(func(string) error); ok { + r0 = rf(uid) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DeleteByAddress provides a mock function with given fields: address +func (_m *Keyring) DeleteByAddress(address types.Address) error { + ret := _m.Called(address) + + var r0 error + if rf, ok := ret.Get(0).(func(types.Address) error); ok { + r0 = rf(address) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ExportPrivKeyArmor provides a mock function with given fields: uid, encryptPassphrase +func (_m *Keyring) ExportPrivKeyArmor(uid string, encryptPassphrase string) (string, error) { + ret := _m.Called(uid, encryptPassphrase) + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(string, string) (string, error)); ok { + return rf(uid, encryptPassphrase) + } + if rf, ok := ret.Get(0).(func(string, string) string); ok { + r0 = rf(uid, encryptPassphrase) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(string, string) error); ok { + r1 = rf(uid, encryptPassphrase) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ExportPrivKeyArmorByAddress provides a mock function with given fields: address, encryptPassphrase +func (_m *Keyring) ExportPrivKeyArmorByAddress(address types.Address, encryptPassphrase string) (string, error) { + ret := _m.Called(address, encryptPassphrase) + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(types.Address, string) (string, error)); ok { + return rf(address, encryptPassphrase) + } + if rf, ok := ret.Get(0).(func(types.Address, string) string); ok { + r0 = rf(address, encryptPassphrase) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(types.Address, string) error); ok { + r1 = rf(address, encryptPassphrase) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ExportPubKeyArmor provides a mock function with given fields: uid +func (_m *Keyring) ExportPubKeyArmor(uid string) (string, error) { + ret := _m.Called(uid) + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(string) (string, error)); ok { + return rf(uid) + } + if rf, ok := ret.Get(0).(func(string) string); ok { + r0 = rf(uid) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(string) error); ok { + r1 = rf(uid) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ExportPubKeyArmorByAddress provides a mock function with given fields: address +func (_m *Keyring) ExportPubKeyArmorByAddress(address types.Address) (string, error) { + ret := _m.Called(address) + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(types.Address) (string, error)); ok { + return rf(address) + } + if rf, ok := ret.Get(0).(func(types.Address) string); ok { + r0 = rf(address) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(types.Address) error); ok { + r1 = rf(address) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ImportPrivKey provides a mock function with given fields: uid, armor, passphrase +func (_m *Keyring) ImportPrivKey(uid string, armor string, passphrase string) error { + ret := _m.Called(uid, armor, passphrase) + + var r0 error + if rf, ok := ret.Get(0).(func(string, string, string) error); ok { + r0 = rf(uid, armor, passphrase) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ImportPrivKeyHex provides a mock function with given fields: uid, privKey, algoStr +func (_m *Keyring) ImportPrivKeyHex(uid string, privKey string, algoStr string) error { + ret := _m.Called(uid, privKey, algoStr) + + var r0 error + if rf, ok := ret.Get(0).(func(string, string, string) error); ok { + r0 = rf(uid, privKey, algoStr) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ImportPubKey provides a mock function with given fields: uid, armor +func (_m *Keyring) ImportPubKey(uid string, armor string) error { + ret := _m.Called(uid, armor) + + var r0 error + if rf, ok := ret.Get(0).(func(string, string) error); ok { + r0 = rf(uid, armor) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Key provides a mock function with given fields: uid +func (_m *Keyring) Key(uid string) (*keyring.Record, error) { + ret := _m.Called(uid) + + var r0 *keyring.Record + var r1 error + if rf, ok := ret.Get(0).(func(string) (*keyring.Record, error)); ok { + return rf(uid) + } + if rf, ok := ret.Get(0).(func(string) *keyring.Record); ok { + r0 = rf(uid) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*keyring.Record) + } + } + + if rf, ok := ret.Get(1).(func(string) error); ok { + r1 = rf(uid) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// KeyByAddress provides a mock function with given fields: address +func (_m *Keyring) KeyByAddress(address types.Address) (*keyring.Record, error) { + ret := _m.Called(address) + + var r0 *keyring.Record + var r1 error + if rf, ok := ret.Get(0).(func(types.Address) (*keyring.Record, error)); ok { + return rf(address) + } + if rf, ok := ret.Get(0).(func(types.Address) *keyring.Record); ok { + r0 = rf(address) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*keyring.Record) + } + } + + if rf, ok := ret.Get(1).(func(types.Address) error); ok { + r1 = rf(address) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// List provides a mock function with given fields: +func (_m *Keyring) List() ([]*keyring.Record, error) { + ret := _m.Called() + + var r0 []*keyring.Record + var r1 error + if rf, ok := ret.Get(0).(func() ([]*keyring.Record, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() []*keyring.Record); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*keyring.Record) + } + } + + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MigrateAll provides a mock function with given fields: +func (_m *Keyring) MigrateAll() ([]*keyring.Record, error) { + ret := _m.Called() + + var r0 []*keyring.Record + var r1 error + if rf, ok := ret.Get(0).(func() ([]*keyring.Record, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() []*keyring.Record); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*keyring.Record) + } + } + + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NewAccount provides a mock function with given fields: uid, mnemonic, bip39Passphrase, hdPath, algo +func (_m *Keyring) NewAccount(uid string, mnemonic string, bip39Passphrase string, hdPath string, algo keyring.SignatureAlgo) (*keyring.Record, error) { + ret := _m.Called(uid, mnemonic, bip39Passphrase, hdPath, algo) + + var r0 *keyring.Record + var r1 error + if rf, ok := ret.Get(0).(func(string, string, string, string, keyring.SignatureAlgo) (*keyring.Record, error)); ok { + return rf(uid, mnemonic, bip39Passphrase, hdPath, algo) + } + if rf, ok := ret.Get(0).(func(string, string, string, string, keyring.SignatureAlgo) *keyring.Record); ok { + r0 = rf(uid, mnemonic, bip39Passphrase, hdPath, algo) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*keyring.Record) + } + } + + if rf, ok := ret.Get(1).(func(string, string, string, string, keyring.SignatureAlgo) error); ok { + r1 = rf(uid, mnemonic, bip39Passphrase, hdPath, algo) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NewMnemonic provides a mock function with given fields: uid, language, hdPath, bip39Passphrase, algo +func (_m *Keyring) NewMnemonic(uid string, language keyring.Language, hdPath string, bip39Passphrase string, algo keyring.SignatureAlgo) (*keyring.Record, string, error) { + ret := _m.Called(uid, language, hdPath, bip39Passphrase, algo) + + var r0 *keyring.Record + var r1 string + var r2 error + if rf, ok := ret.Get(0).(func(string, keyring.Language, string, string, keyring.SignatureAlgo) (*keyring.Record, string, error)); ok { + return rf(uid, language, hdPath, bip39Passphrase, algo) + } + if rf, ok := ret.Get(0).(func(string, keyring.Language, string, string, keyring.SignatureAlgo) *keyring.Record); ok { + r0 = rf(uid, language, hdPath, bip39Passphrase, algo) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*keyring.Record) + } + } + + if rf, ok := ret.Get(1).(func(string, keyring.Language, string, string, keyring.SignatureAlgo) string); ok { + r1 = rf(uid, language, hdPath, bip39Passphrase, algo) + } else { + r1 = ret.Get(1).(string) + } + + if rf, ok := ret.Get(2).(func(string, keyring.Language, string, string, keyring.SignatureAlgo) error); ok { + r2 = rf(uid, language, hdPath, bip39Passphrase, algo) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// Rename provides a mock function with given fields: from, to +func (_m *Keyring) Rename(from string, to string) error { + ret := _m.Called(from, to) + + var r0 error + if rf, ok := ret.Get(0).(func(string, string) error); ok { + r0 = rf(from, to) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// SaveLedgerKey provides a mock function with given fields: uid, algo, hrp, coinType, account, index +func (_m *Keyring) SaveLedgerKey(uid string, algo keyring.SignatureAlgo, hrp string, coinType uint32, account uint32, index uint32) (*keyring.Record, error) { + ret := _m.Called(uid, algo, hrp, coinType, account, index) + + var r0 *keyring.Record + var r1 error + if rf, ok := ret.Get(0).(func(string, keyring.SignatureAlgo, string, uint32, uint32, uint32) (*keyring.Record, error)); ok { + return rf(uid, algo, hrp, coinType, account, index) + } + if rf, ok := ret.Get(0).(func(string, keyring.SignatureAlgo, string, uint32, uint32, uint32) *keyring.Record); ok { + r0 = rf(uid, algo, hrp, coinType, account, index) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*keyring.Record) + } + } + + if rf, ok := ret.Get(1).(func(string, keyring.SignatureAlgo, string, uint32, uint32, uint32) error); ok { + r1 = rf(uid, algo, hrp, coinType, account, index) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// SaveMultisig provides a mock function with given fields: uid, pubkey +func (_m *Keyring) SaveMultisig(uid string, pubkey cryptotypes.PubKey) (*keyring.Record, error) { + ret := _m.Called(uid, pubkey) + + var r0 *keyring.Record + var r1 error + if rf, ok := ret.Get(0).(func(string, cryptotypes.PubKey) (*keyring.Record, error)); ok { + return rf(uid, pubkey) + } + if rf, ok := ret.Get(0).(func(string, cryptotypes.PubKey) *keyring.Record); ok { + r0 = rf(uid, pubkey) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*keyring.Record) + } + } + + if rf, ok := ret.Get(1).(func(string, cryptotypes.PubKey) error); ok { + r1 = rf(uid, pubkey) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// SaveOfflineKey provides a mock function with given fields: uid, pubkey +func (_m *Keyring) SaveOfflineKey(uid string, pubkey cryptotypes.PubKey) (*keyring.Record, error) { + ret := _m.Called(uid, pubkey) + + var r0 *keyring.Record + var r1 error + if rf, ok := ret.Get(0).(func(string, cryptotypes.PubKey) (*keyring.Record, error)); ok { + return rf(uid, pubkey) + } + if rf, ok := ret.Get(0).(func(string, cryptotypes.PubKey) *keyring.Record); ok { + r0 = rf(uid, pubkey) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*keyring.Record) + } + } + + if rf, ok := ret.Get(1).(func(string, cryptotypes.PubKey) error); ok { + r1 = rf(uid, pubkey) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Sign provides a mock function with given fields: uid, msg, signMode +func (_m *Keyring) Sign(uid string, msg []byte, signMode signing.SignMode) ([]byte, cryptotypes.PubKey, error) { + ret := _m.Called(uid, msg, signMode) + + var r0 []byte + var r1 cryptotypes.PubKey + var r2 error + if rf, ok := ret.Get(0).(func(string, []byte, signing.SignMode) ([]byte, cryptotypes.PubKey, error)); ok { + return rf(uid, msg, signMode) + } + if rf, ok := ret.Get(0).(func(string, []byte, signing.SignMode) []byte); ok { + r0 = rf(uid, msg, signMode) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + if rf, ok := ret.Get(1).(func(string, []byte, signing.SignMode) cryptotypes.PubKey); ok { + r1 = rf(uid, msg, signMode) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(cryptotypes.PubKey) + } + } + + if rf, ok := ret.Get(2).(func(string, []byte, signing.SignMode) error); ok { + r2 = rf(uid, msg, signMode) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// SignByAddress provides a mock function with given fields: address, msg, signMode +func (_m *Keyring) SignByAddress(address types.Address, msg []byte, signMode signing.SignMode) ([]byte, cryptotypes.PubKey, error) { + ret := _m.Called(address, msg, signMode) + + var r0 []byte + var r1 cryptotypes.PubKey + var r2 error + if rf, ok := ret.Get(0).(func(types.Address, []byte, signing.SignMode) ([]byte, cryptotypes.PubKey, error)); ok { + return rf(address, msg, signMode) + } + if rf, ok := ret.Get(0).(func(types.Address, []byte, signing.SignMode) []byte); ok { + r0 = rf(address, msg, signMode) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + if rf, ok := ret.Get(1).(func(types.Address, []byte, signing.SignMode) cryptotypes.PubKey); ok { + r1 = rf(address, msg, signMode) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(cryptotypes.PubKey) + } + } + + if rf, ok := ret.Get(2).(func(types.Address, []byte, signing.SignMode) error); ok { + r2 = rf(address, msg, signMode) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// SupportedAlgorithms provides a mock function with given fields: +func (_m *Keyring) SupportedAlgorithms() (keyring.SigningAlgoList, keyring.SigningAlgoList) { + ret := _m.Called() + + var r0 keyring.SigningAlgoList + var r1 keyring.SigningAlgoList + if rf, ok := ret.Get(0).(func() (keyring.SigningAlgoList, keyring.SigningAlgoList)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() keyring.SigningAlgoList); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(keyring.SigningAlgoList) + } + } + + if rf, ok := ret.Get(1).(func() keyring.SigningAlgoList); ok { + r1 = rf() + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(keyring.SigningAlgoList) + } + } + + return r0, r1 +} + +type mockConstructorTestingTNewKeyring interface { + mock.TestingT + Cleanup(func()) +} + +// NewKeyring creates a new instance of Keyring. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewKeyring(t mockConstructorTestingTNewKeyring) *Keyring { + mock := &Keyring{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/app/proposal_handler_test.go b/app/proposal_handler_test.go index f3cab590a..e401841dd 100644 --- a/app/proposal_handler_test.go +++ b/app/proposal_handler_test.go @@ -4,7 +4,6 @@ import ( "encoding/hex" "encoding/json" "errors" - "fmt" "os" "testing" @@ -116,7 +115,6 @@ func (s *ProposalHandlerTestSuite) TestCheckOracleAttestationsFromLastCommit() { require.Equal(voteExt.OracleAttestations[0].Attestation, att[0]) require.Equal(voteExt.OracleAttestations[0].Snapshot, snap[0]) require.Equal(valAddr.String(), addrs[0]) - fmt.Println("addrs: ", addrs, "\natt: ", att, "\nsnap: ", snap) } func (s *ProposalHandlerTestSuite) TestSetEVMAddresses() { @@ -254,7 +252,6 @@ func (s *ProposalHandlerTestSuite) TestPrepareProposalHandler() ([][]byte, sdk.A } res, err := p.PrepareProposalHandler(ctx, &req) - fmt.Println("res: ", res, "\nerr: ", err) require.NoError(err) require.NotNil(res) diff --git a/daemons/token_bridge_feed/abi/TokenBridge.go b/daemons/token_bridge_feed/abi/TokenBridge.go index d4d07d992..f55d30fe0 100644 --- a/daemons/token_bridge_feed/abi/TokenBridge.go +++ b/daemons/token_bridge_feed/abi/TokenBridge.go @@ -60,8 +60,8 @@ type Validator struct { // TokenBridgeMetaData contains all meta data concerning the TokenBridge contract. var TokenBridgeMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_blobstream\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"depositId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"recipient\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"depositId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"sender\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DEPOSIT_LIMIT_PERCENTAGE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DEPOSIT_LIMIT_UPDATE_INTERVAL\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_ATTESTATION_AGE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridge\",\"outputs\":[{\"internalType\":\"contractBlobstreamO\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentDepositLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"depositId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"depositLimitUpdateTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_layerRecipient\",\"type\":\"string\"}],\"name\":\"depositToLayer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"recipient\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockHeight\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"queryId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"value\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"aggregatePower\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"previousTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nextTimestamp\",\"type\":\"uint256\"}],\"internalType\":\"structReportData\",\"name\":\"report\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"attestationTimestamp\",\"type\":\"uint256\"}],\"internalType\":\"structOracleAttestationData\",\"name\":\"_attest\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"power\",\"type\":\"uint256\"}],\"internalType\":\"structValidator[]\",\"name\":\"_currentValidatorSet\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structSignature[]\",\"name\":\"_sigs\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"_fallbackTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_fallbackMinimumPower\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxAttestationAge\",\"type\":\"uint256\"}],\"name\":\"getDataWithFallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"queryId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"value\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"aggregatePower\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"previousTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nextTimestamp\",\"type\":\"uint256\"}],\"internalType\":\"structReportData\",\"name\":\"report\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"attestationTimestamp\",\"type\":\"uint256\"}],\"internalType\":\"structOracleAttestationData\",\"name\":\"_attest\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"power\",\"type\":\"uint256\"}],\"internalType\":\"structValidator[]\",\"name\":\"_currentValidatorSet\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structSignature[]\",\"name\":\"_sigs\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"_maxAttestationAge\",\"type\":\"uint256\"}],\"name\":\"isAnyConsensusValue\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"queryId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"value\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"aggregatePower\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"previousTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nextTimestamp\",\"type\":\"uint256\"}],\"internalType\":\"structReportData\",\"name\":\"report\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"attestationTimestamp\",\"type\":\"uint256\"}],\"internalType\":\"structOracleAttestationData\",\"name\":\"_attest\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"power\",\"type\":\"uint256\"}],\"internalType\":\"structValidator[]\",\"name\":\"_currentValidatorSet\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structSignature[]\",\"name\":\"_sigs\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"_maxAttestationAge\",\"type\":\"uint256\"}],\"name\":\"isCurrentConsensusValue\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"queryId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"value\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"aggregatePower\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"previousTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nextTimestamp\",\"type\":\"uint256\"}],\"internalType\":\"structReportData\",\"name\":\"report\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"attestationTimestamp\",\"type\":\"uint256\"}],\"internalType\":\"structOracleAttestationData\",\"name\":\"_attest\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"power\",\"type\":\"uint256\"}],\"internalType\":\"structValidator[]\",\"name\":\"_currentValidatorSet\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structSignature[]\",\"name\":\"_sigs\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"_timestampAfter\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxAge\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_minimumPower\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxAttestationAge\",\"type\":\"uint256\"}],\"name\":\"isValidDataAfter\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"queryId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"value\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"aggregatePower\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"previousTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nextTimestamp\",\"type\":\"uint256\"}],\"internalType\":\"structReportData\",\"name\":\"report\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"attestationTimestamp\",\"type\":\"uint256\"}],\"internalType\":\"structOracleAttestationData\",\"name\":\"_attest\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"power\",\"type\":\"uint256\"}],\"internalType\":\"structValidator[]\",\"name\":\"_currentValidatorSet\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structSignature[]\",\"name\":\"_sigs\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"_timestampBefore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxReportAge\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_minimumPower\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxAttestationAge\",\"type\":\"uint256\"}],\"name\":\"isValidDataBefore\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"token\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"queryId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"value\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"aggregatePower\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"previousTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nextTimestamp\",\"type\":\"uint256\"}],\"internalType\":\"structReportData\",\"name\":\"report\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"attestationTimestamp\",\"type\":\"uint256\"}],\"internalType\":\"structOracleAttestationData\",\"name\":\"_attest\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"power\",\"type\":\"uint256\"}],\"internalType\":\"structValidator[]\",\"name\":\"_valset\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structSignature[]\",\"name\":\"_sigs\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"_depositId\",\"type\":\"uint256\"}],\"name\":\"withdrawFromLayer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"withdrawalClaimed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x608060405234801562000010575f80fd5b50604051620037ef380380620037ef83398181016040528101906200003691906200012b565b80805f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550508160015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555042600381905550505062000170565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f620000f582620000ca565b9050919050565b6200010781620000e9565b811462000112575f80fd5b50565b5f815190506200012581620000fc565b92915050565b5f8060408385031215620001445762000143620000c6565b5b5f620001538582860162000115565b9250506020620001668582860162000115565b9150509250929050565b613671806200017e5f395ff3fe608060405234801561000f575f80fd5b5060043610610109575f3560e01c80636329f706116100a0578063e2f8b4b51161006f578063e2f8b4b5146102f4578063e5d8b9dc14610312578063e78cea921461032e578063fa3c06d21461034c578063fc0c546a1461036a57610109565b80636329f706146102555780639852099c14610285578063b02c43d0146102a3578063b9f7bb8d146102d657610109565b806350b5c02d116100dc57806350b5c02d146101bb5780635f96ca6c146101eb578063601319eb14610207578063604f918f1461023757610109565b80630295d71b1461010d5780630dc91aab1461012b5780631d8218541461015b5780633113975b1461018b575b5f80fd5b610115610388565b60405161012291906117f7565b60405180910390f35b61014560048036038101906101409190611923565b61038e565b60405161015291906119fc565b60405180910390f35b61017560048036038101906101709190611a15565b6104ce565b60405161018291906119fc565b60405180910390f35b6101a560048036038101906101a09190611a40565b6104eb565b6040516101b291906119fc565b60405180910390f35b6101d560048036038101906101d09190611b38565b6107aa565b6040516101e291906119fc565b60405180910390f35b61020560048036038101906102009190611d56565b610b93565b005b610221600480360381019061021c9190611923565b610e29565b60405161022e91906119fc565b60405180910390f35b61023f610fbe565b60405161024c91906117f7565b60405180910390f35b61026f600480360381019061026a9190611a40565b610fc4565b60405161027c91906119fc565b60405180910390f35b61028d611283565b60405161029a91906117f7565b60405180910390f35b6102bd60048036038101906102b89190611a15565b611289565b6040516102cd9493929190611e69565b60405180910390f35b6102de61135a565b6040516102eb91906117f7565b60405180910390f35b6102fc611361565b60405161030991906117f7565b60405180910390f35b61032c60048036038101906103279190611923565b61136e565b005b61033661169f565b6040516103439190611f0e565b60405180910390f35b6103546116c2565b60405161036191906117f7565b60405180910390f35b6103726116c8565b60405161037f9190611f47565b60405180910390f35b60045481565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c312b38088888888886040518663ffffffff1660e01b81526004016103f0959493929190612431565b602060405180830381865afa15801561040b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061042f91906124a9565b61046e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104659061251e565b60405180910390fd5b8187604001354261047f9190612569565b11156104c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104b7906125e6565b60405180910390fd5b600190509695505050505050565b6005602052805f5260405f205f915054906101000a900460ff1681565b5f818a60400135426104fd9190612569565b111561053e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610535906125e6565b60405180910390fd5b848a806020019061054f9190612610565b6020013510610593576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058a906126a7565b60405180910390fd5b5f8a80602001906105a49190612610565b6080013514806105c65750848a80602001906105c09190612610565b60800135115b610605576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105fc90612735565b60405180910390fd5b828a80602001906106169190612610565b60400135101561065b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610652906127e9565b60405180910390fd5b838a806020019061066c9190612610565b602001354261067b9190612569565b106106bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b290612851565b60405180910390fd5b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635121b26e8b8b8b8b8b6040518663ffffffff1660e01b815260040161071b959493929190612431565b602060405180830381865afa158015610736573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061075a91906124a9565b610799576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610790906128b9565b60405180910390fd5b600190509998505050505050505050565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635121b26e8a8a8a8a8a6040518663ffffffff1660e01b815260040161080c959493929190612431565b602060405180830381865afa158015610827573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061084b91906124a9565b61088a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610881906128b9565b60405180910390fd5b8189604001354261089b9190612569565b11156108dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108d3906125e6565b60405180910390fd5b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ba95ec276040518163ffffffff1660e01b8152600401602060405180830381865afa158015610944573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061096891906128eb565b8980602001906109789190612610565b60400135106109d757838980602001906109929190612610565b60200135106109d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109cd90612986565b60405180910390fd5b5b5f8980602001906109e89190612610565b608001351480610a0a575083898060200190610a049190612610565b60800135115b610a49576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4090612735565b60405180910390fd5b82898060200190610a5a9190612610565b604001351015610a9f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a96906127e9565b60405180910390fd5b5f898060200190610ab09190612610565b608001351480610ad2575083898060200190610acc9190612610565b60800135105b610b11576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0890612a14565b60405180910390fd5b5f898060200190610b229190612610565b608001351480610b44575083898060200190610b3e9190612610565b60800135115b610b83576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b7a90612aa2565b60405180910390fd5b6001905098975050505050505050565b5f8211610bd5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bcc90612b30565b60405180910390fd5b610bdd6116ed565b821115610c1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c1690612bbe565b60405180910390fd5b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b8152600401610c7d93929190612bdc565b6020604051808303815f875af1158015610c99573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cbd91906124a9565b610cfc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cf390612c5b565b60405180910390fd5b60025f815480929190610d0e90612c79565b91905055508160045f828254610d249190612569565b9250508190555060405180608001604052803373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020018381526020014381525060065f60025481526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001019081610dce9190612eb1565b5060408201518160020155606082015181600301559050507faeefb35576420985ebd638138c7f004039a2154c74d548ae18603b54a5f1bdc5600254338385604051610e1d9493929190612f80565b60405180910390a15050565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c312b38088888888886040518663ffffffff1660e01b8152600401610e8b959493929190612431565b602060405180830381865afa158015610ea6573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610eca91906124a9565b610f09576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f009061251e565b60405180910390fd5b81876040013542610f1a9190612569565b1115610f5b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f52906125e6565b60405180910390fd5b5f878060200190610f6c9190612610565b6080013514610fb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fa790613014565b60405180910390fd5b600190509695505050505050565b61a8c081565b5f818a6040013542610fd69190612569565b1115611017576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161100e906125e6565b60405180910390fd5b848a80602001906110289190612610565b602001351161106c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611063906130a2565b60405180910390fd5b5f8a806020019061107d9190612610565b60800135148061109f5750848a80602001906110999190612610565b60800135115b6110de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110d590612735565b60405180910390fd5b828a80602001906110ef9190612610565b604001351015611134576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161112b906127e9565b60405180910390fd5b838a80602001906111459190612610565b60200135426111549190612569565b10611194576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118b90612851565b60405180910390fd5b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635121b26e8b8b8b8b8b6040518663ffffffff1660e01b81526004016111f4959493929190612431565b602060405180830381865afa15801561120f573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061123391906124a9565b611272576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611269906128b9565b60405180910390fd5b600190509998505050505050505050565b60025481565b6006602052805f5260405f205f91509050805f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010180546112cd90612ced565b80601f01602080910402602001604051908101604052809291908181526020018280546112f990612ced565b80156113445780601f1061131b57610100808354040283529160200191611344565b820191905f5260205f20905b81548152906001019060200180831161132757829003601f168201915b5050505050908060020154908060030154905084565b6201518081565b6801158e460913d0000081565b5f816040516020016113819291906130c0565b6040516020818303038152906040526040516020016113a09190613183565b60405160208183030381529060405280519060200120865f0135146113fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113f190613200565b60405180910390fd5b60055f8281526020019081526020015f205f9054906101000a900460ff1615611458576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161144f9061328e565b60405180910390fd5b61a8c086806020019061146b9190612610565b602001354261147a9190612569565b116114ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114b19061331c565b60405180910390fd5b6114cb86868686866201518061038e565b61150a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161150190613384565b60405180910390fd5b600160055f8381526020019081526020015f205f6101000a81548160ff0219169083151502179055505f805f8880602001906115469190612610565b805f019061155491906133a2565b810190611561919061343f565b9250925092505f64e8d4a510008261157991906134ab565b905060015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85836040518363ffffffff1660e01b81526004016115d79291906134ec565b6020604051808303815f875af11580156115f3573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061161791906124a9565b611656576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161164d9061355d565b60405180910390fd5b7f1c25a916bf61b55f3abb9060e620d13d6937f8c2ab2b7a16be824ffde44acb2f8584868460405161168b949392919061357b565b60405180910390a150505050505050505050565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60035481565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f8060015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161174991906135c5565b602060405180830381865afa158015611764573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061178891906128eb565b905061a8c06003544261179b9190612569565b11156117d657662386f26fc100006801158e460913d00000826117be91906134ab565b6117c8919061360b565b600481905550426003819055505b60045491505090565b5f819050919050565b6117f1816117df565b82525050565b5f60208201905061180a5f8301846117e8565b92915050565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f6060828403121561183a57611839611821565b5b81905092915050565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261186457611863611843565b5b8235905067ffffffffffffffff81111561188157611880611847565b5b60208301915083604082028301111561189d5761189c61184b565b5b9250929050565b5f8083601f8401126118b9576118b8611843565b5b8235905067ffffffffffffffff8111156118d6576118d5611847565b5b6020830191508360608202830111156118f2576118f161184b565b5b9250929050565b611902816117df565b811461190c575f80fd5b50565b5f8135905061191d816118f9565b92915050565b5f805f805f806080878903121561193d5761193c611819565b5b5f87013567ffffffffffffffff81111561195a5761195961181d565b5b61196689828a01611825565b965050602087013567ffffffffffffffff8111156119875761198661181d565b5b61199389828a0161184f565b9550955050604087013567ffffffffffffffff8111156119b6576119b561181d565b5b6119c289828a016118a4565b935093505060606119d589828a0161190f565b9150509295509295509295565b5f8115159050919050565b6119f6816119e2565b82525050565b5f602082019050611a0f5f8301846119ed565b92915050565b5f60208284031215611a2a57611a29611819565b5b5f611a378482850161190f565b91505092915050565b5f805f805f805f805f60e08a8c031215611a5d57611a5c611819565b5b5f8a013567ffffffffffffffff811115611a7a57611a7961181d565b5b611a868c828d01611825565b99505060208a013567ffffffffffffffff811115611aa757611aa661181d565b5b611ab38c828d0161184f565b985098505060408a013567ffffffffffffffff811115611ad657611ad561181d565b5b611ae28c828d016118a4565b96509650506060611af58c828d0161190f565b9450506080611b068c828d0161190f565b93505060a0611b178c828d0161190f565b92505060c0611b288c828d0161190f565b9150509295985092959850929598565b5f805f805f805f8060c0898b031215611b5457611b53611819565b5b5f89013567ffffffffffffffff811115611b7157611b7061181d565b5b611b7d8b828c01611825565b985050602089013567ffffffffffffffff811115611b9e57611b9d61181d565b5b611baa8b828c0161184f565b9750975050604089013567ffffffffffffffff811115611bcd57611bcc61181d565b5b611bd98b828c016118a4565b95509550506060611bec8b828c0161190f565b9350506080611bfd8b828c0161190f565b92505060a0611c0e8b828c0161190f565b9150509295985092959890939650565b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b611c6882611c22565b810181811067ffffffffffffffff82111715611c8757611c86611c32565b5b80604052505050565b5f611c99611810565b9050611ca58282611c5f565b919050565b5f67ffffffffffffffff821115611cc457611cc3611c32565b5b611ccd82611c22565b9050602081019050919050565b828183375f83830152505050565b5f611cfa611cf584611caa565b611c90565b905082815260208101848484011115611d1657611d15611c1e565b5b611d21848285611cda565b509392505050565b5f82601f830112611d3d57611d3c611843565b5b8135611d4d848260208601611ce8565b91505092915050565b5f8060408385031215611d6c57611d6b611819565b5b5f611d798582860161190f565b925050602083013567ffffffffffffffff811115611d9a57611d9961181d565b5b611da685828601611d29565b9150509250929050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611dd982611db0565b9050919050565b611de981611dcf565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015611e26578082015181840152602081019050611e0b565b5f8484015250505050565b5f611e3b82611def565b611e458185611df9565b9350611e55818560208601611e09565b611e5e81611c22565b840191505092915050565b5f608082019050611e7c5f830187611de0565b8181036020830152611e8e8186611e31565b9050611e9d60408301856117e8565b611eaa60608301846117e8565b95945050505050565b5f819050919050565b5f611ed6611ed1611ecc84611db0565b611eb3565b611db0565b9050919050565b5f611ee782611ebc565b9050919050565b5f611ef882611edd565b9050919050565b611f0881611eee565b82525050565b5f602082019050611f215f830184611eff565b92915050565b5f611f3182611edd565b9050919050565b611f4181611f27565b82525050565b5f602082019050611f5a5f830184611f38565b92915050565b5f819050919050565b611f7281611f60565b8114611f7c575f80fd5b50565b5f81359050611f8d81611f69565b92915050565b5f611fa16020840184611f7f565b905092915050565b611fb281611f60565b82525050565b5f80fd5b5f8235600160a003833603038112611fd757611fd6611fb8565b5b82810191505092915050565b5f80fd5b5f80fd5b5f808335600160200384360303811261200757612006611fb8565b5b83810192508235915060208301925067ffffffffffffffff82111561202f5761202e611fe3565b5b60018202360383131561204557612044611fe7565b5b509250929050565b5f82825260208201905092915050565b5f612068838561204d565b9350612075838584611cda565b61207e83611c22565b840190509392505050565b5f612097602084018461190f565b905092915050565b6120a8816117df565b82525050565b5f60a083016120bf5f840184611feb565b8583035f8701526120d183828461205d565b925050506120e26020840184612089565b6120ef602086018261209f565b506120fd6040840184612089565b61210a604086018261209f565b506121186060840184612089565b612125606086018261209f565b506121336080840184612089565b612140608086018261209f565b508091505092915050565b5f6060830161215c5f840184611f93565b6121685f860182611fa9565b506121766020840184611fbc565b848203602086015261218882826120ae565b9150506121986040840184612089565b6121a5604086018261209f565b508091505092915050565b5f82825260208201905092915050565b5f819050919050565b6121d281611dcf565b81146121dc575f80fd5b50565b5f813590506121ed816121c9565b92915050565b5f61220160208401846121df565b905092915050565b61221281611dcf565b82525050565b604082016122285f8301836121f3565b6122345f850182612209565b506122426020830183612089565b61224f602085018261209f565b50505050565b5f6122608383612218565b60408301905092915050565b5f82905092915050565b5f604082019050919050565b5f61228d83856121b0565b9350612298826121c0565b805f5b858110156122d0576122ad828461226c565b6122b78882612255565b97506122c283612276565b92505060018101905061229b565b5085925050509392505050565b5f82825260208201905092915050565b5f819050919050565b5f60ff82169050919050565b61230b816122f6565b8114612315575f80fd5b50565b5f8135905061232681612302565b92915050565b5f61233a6020840184612318565b905092915050565b61234b816122f6565b82525050565b606082016123615f83018361232c565b61236d5f850182612342565b5061237b6020830183611f93565b6123886020850182611fa9565b506123966040830183611f93565b6123a36040850182611fa9565b50505050565b5f6123b48383612351565b60608301905092915050565b5f82905092915050565b5f606082019050919050565b5f6123e183856122dd565b93506123ec826122ed565b805f5b858110156124245761240182846123c0565b61240b88826123a9565b9750612416836123ca565b9250506001810190506123ef565b5085925050509392505050565b5f6060820190508181035f830152612449818861214b565b9050818103602083015261245e818688612282565b905081810360408301526124738184866123d6565b90509695505050505050565b612488816119e2565b8114612492575f80fd5b50565b5f815190506124a38161247f565b92915050565b5f602082840312156124be576124bd611819565b5b5f6124cb84828501612495565b91505092915050565b7f496e76616c6964206174746573746174696f6e000000000000000000000000005f82015250565b5f612508601383611df9565b9150612513826124d4565b602082019050919050565b5f6020820190508181035f830152612535816124fc565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612573826117df565b915061257e836117df565b92508282039050818111156125965761259561253c565b5b92915050565b7f4174746573746174696f6e20697320746f6f206f6c64000000000000000000005f82015250565b5f6125d0601683611df9565b91506125db8261259c565b602082019050919050565b5f6020820190508181035f8301526125fd816125c4565b9050919050565b5f80fd5b5f80fd5b5f80fd5b5f8235600160a00383360303811261262b5761262a612604565b5b80830191505092915050565b7f5265706f72742074696d657374616d70206d757374206265206265666f7265205f8201527f5f74696d657374616d704265666f726500000000000000000000000000000000602082015250565b5f612691603083611df9565b915061269c82612637565b604082019050919050565b5f6020820190508181035f8301526126be81612685565b9050919050565b7f5265706f7274206973206c6174657374206265666f72652074696d657374616d5f8201527f7000000000000000000000000000000000000000000000000000000000000000602082015250565b5f61271f602183611df9565b915061272a826126c5565b604082019050919050565b5f6020820190508181035f83015261274c81612713565b9050919050565b7f5265706f72742061676772656761746520706f776572206d75737420626520675f8201527f726561746572207468616e206f7220657175616c20746f205f6d696e696d756d60208201527f506f776572000000000000000000000000000000000000000000000000000000604082015250565b5f6127d3604583611df9565b91506127de82612753565b606082019050919050565b5f6020820190508181035f830152612800816127c7565b9050919050565b7f5265706f727420697320746f6f206f6c640000000000000000000000000000005f82015250565b5f61283b601183611df9565b915061284682612807565b602082019050919050565b5f6020820190508181035f8301526128688161282f565b9050919050565b7f496e76616c6964207369676e61747572650000000000000000000000000000005f82015250565b5f6128a3601183611df9565b91506128ae8261286f565b602082019050919050565b5f6020820190508181035f8301526128d081612897565b9050919050565b5f815190506128e5816118f9565b92915050565b5f60208284031215612900576128ff611819565b5b5f61290d848285016128d7565b91505092915050565b7f5265706f72742074696d657374616d70206d757374206265206265666f7265205f8201527f5f66616c6c6261636b54696d657374616d700000000000000000000000000000602082015250565b5f612970603283611df9565b915061297b82612916565b604082019050919050565b5f6020820190508181035f83015261299d81612964565b9050919050565b7f5265706f7274206973206c61746573742061667465722066616c6c6261636b205f8201527f74696d657374616d700000000000000000000000000000000000000000000000602082015250565b5f6129fe602983611df9565b9150612a09826129a4565b604082019050919050565b5f6020820190508181035f830152612a2b816129f2565b9050919050565b7f5265706f7274206973206c6174657374206265666f72652066616c6c6261636b5f8201527f2074696d657374616d7000000000000000000000000000000000000000000000602082015250565b5f612a8c602a83611df9565b9150612a9782612a32565b604082019050919050565b5f6020820190508181035f830152612ab981612a80565b9050919050565b7f546f6b656e4272696467653a20616d6f756e74206d75737420626520677265615f8201527f746572207468616e203000000000000000000000000000000000000000000000602082015250565b5f612b1a602a83611df9565b9150612b2582612ac0565b604082019050919050565b5f6020820190508181035f830152612b4781612b0e565b9050919050565b7f546f6b656e4272696467653a20616d6f756e742065786365656473206465706f5f8201527f736974206c696d69740000000000000000000000000000000000000000000000602082015250565b5f612ba8602983611df9565b9150612bb382612b4e565b604082019050919050565b5f6020820190508181035f830152612bd581612b9c565b9050919050565b5f606082019050612bef5f830186611de0565b612bfc6020830185611de0565b612c0960408301846117e8565b949350505050565b7f546f6b656e4272696467653a207472616e7366657246726f6d206661696c65645f82015250565b5f612c45602083611df9565b9150612c5082612c11565b602082019050919050565b5f6020820190508181035f830152612c7281612c39565b9050919050565b5f612c83826117df565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612cb557612cb461253c565b5b600182019050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680612d0457607f821691505b602082108103612d1757612d16612cc0565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302612d797fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82612d3e565b612d838683612d3e565b95508019841693508086168417925050509392505050565b5f612db5612db0612dab846117df565b611eb3565b6117df565b9050919050565b5f819050919050565b612dce83612d9b565b612de2612dda82612dbc565b848454612d4a565b825550505050565b5f90565b612df6612dea565b612e01818484612dc5565b505050565b5b81811015612e2457612e195f82612dee565b600181019050612e07565b5050565b601f821115612e6957612e3a81612d1d565b612e4384612d2f565b81016020851015612e52578190505b612e66612e5e85612d2f565b830182612e06565b50505b505050565b5f82821c905092915050565b5f612e895f1984600802612e6e565b1980831691505092915050565b5f612ea18383612e7a565b9150826002028217905092915050565b612eba82611def565b67ffffffffffffffff811115612ed357612ed2611c32565b5b612edd8254612ced565b612ee8828285612e28565b5f60209050601f831160018114612f19575f8415612f07578287015190505b612f118582612e96565b865550612f78565b601f198416612f2786612d1d565b5f5b82811015612f4e57848901518255600182019150602085019450602081019050612f29565b86831015612f6b5784890151612f67601f891682612e7a565b8355505b6001600288020188555050505b505050505050565b5f608082019050612f935f8301876117e8565b612fa06020830186611de0565b8181036040830152612fb28185611e31565b9050612fc160608301846117e8565b95945050505050565b7f5265706f7274206973206e6f74206c61746573740000000000000000000000005f82015250565b5f612ffe601483611df9565b915061300982612fca565b602082019050919050565b5f6020820190508181035f83015261302b81612ff2565b9050919050565b7f5265706f72742074696d657374616d70206d757374206265206166746572205f5f8201527f74696d657374616d700000000000000000000000000000000000000000000000602082015250565b5f61308c602983611df9565b915061309782613032565b604082019050919050565b5f6020820190508181035f8301526130b981613080565b9050919050565b5f6040820190506130d35f8301856119ed565b6130e060208301846117e8565b9392505050565b7f54524242726964676500000000000000000000000000000000000000000000005f82015250565b5f61311b600983611df9565b9150613126826130e7565b602082019050919050565b5f81519050919050565b5f82825260208201905092915050565b5f61315582613131565b61315f818561313b565b935061316f818560208601611e09565b61317881611c22565b840191505092915050565b5f6040820190508181035f83015261319a8161310f565b905081810360208301526131ae818461314b565b905092915050565b7f546f6b656e4272696467653a20696e76616c69642071756572794964000000005f82015250565b5f6131ea601c83611df9565b91506131f5826131b6565b602082019050919050565b5f6020820190508181035f830152613217816131de565b9050919050565b7f546f6b656e4272696467653a207769746864726177616c20616c7265616479205f8201527f636c61696d656400000000000000000000000000000000000000000000000000602082015250565b5f613278602783611df9565b91506132838261321e565b604082019050919050565b5f6020820190508181035f8301526132a58161326c565b9050919050565b7f546f6b656e4272696467653a207072656d6174757265206174746573746174695f8201527f6f6e000000000000000000000000000000000000000000000000000000000000602082015250565b5f613306602283611df9565b9150613311826132ac565b604082019050919050565b5f6020820190508181035f830152613333816132fa565b9050919050565b7f546f6b656e4272696467653a20696e76616c6964206174746573746174696f6e5f82015250565b5f61336e602083611df9565b91506133798261333a565b602082019050919050565b5f6020820190508181035f83015261339b81613362565b9050919050565b5f80833560016020038436030381126133be576133bd612604565b5b80840192508235915067ffffffffffffffff8211156133e0576133df612608565b5b6020830192506001820236038313156133fc576133fb61260c565b5b509250929050565b5f61340e82611db0565b9050919050565b61341e81613404565b8114613428575f80fd5b50565b5f8135905061343981613415565b92915050565b5f805f6060848603121561345657613455611819565b5b5f6134638682870161342b565b935050602084013567ffffffffffffffff8111156134845761348361181d565b5b61349086828701611d29565b92505060406134a18682870161190f565b9150509250925092565b5f6134b5826117df565b91506134c0836117df565b92508282026134ce816117df565b915082820484148315176134e5576134e461253c565b5b5092915050565b5f6040820190506134ff5f830185611de0565b61350c60208301846117e8565b9392505050565b7f546f6b656e4272696467653a207472616e73666572206661696c6564000000005f82015250565b5f613547601c83611df9565b915061355282613513565b602082019050919050565b5f6020820190508181035f8301526135748161353b565b9050919050565b5f60808201905061358e5f8301876117e8565b81810360208301526135a08186611e31565b90506135af6040830185611de0565b6135bc60608301846117e8565b95945050505050565b5f6020820190506135d85f830184611de0565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f613615826117df565b9150613620836117df565b9250826136305761362f6135de565b5b82820490509291505056fea26469706673582212209b762d8681410c515f6b203971bbf6facc05d876e45b669b17ca308c4496632464736f6c63430008160033", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_blobstream\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_tellorFlex\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_depositId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_recipient\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_tip\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_depositId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_sender\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DEPOSIT_LIMIT_DENOMINATOR\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DEPOSIT_LIMIT_UPDATE_INTERVAL\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"addStakingRewards\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridge\",\"outputs\":[{\"internalType\":\"contractBlobstreamO\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"}],\"name\":\"claimExtraWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"depositId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"depositLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"depositLimitRecord\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"depositLimitUpdateTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_tip\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_layerRecipient\",\"type\":\"string\"}],\"name\":\"depositToLayer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"recipient\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tip\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockHeight\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_queryId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_timestamp\",\"type\":\"uint256\"}],\"name\":\"getDataBefore\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"_ifRetrieve\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"_value\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_timestampRetrieved\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_queryId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_timestamp\",\"type\":\"uint256\"}],\"name\":\"getIndexForDataBefore\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"_found\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_queryId\",\"type\":\"bytes32\"}],\"name\":\"getNewValueCountbyQueryId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_queryId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_timestamp\",\"type\":\"uint256\"}],\"name\":\"getReporterByTimestamp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTimeOfLastNewValue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_queryId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getTimestampbyQueryIdandIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_queryId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_timestamp\",\"type\":\"uint256\"}],\"name\":\"isInDispute\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tellorFlex\",\"outputs\":[{\"internalType\":\"contractITellorFlex\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"token\",\"outputs\":[{\"internalType\":\"contractITellorMaster\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"tokensToClaim\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"queryId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"value\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"aggregatePower\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"previousTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nextTimestamp\",\"type\":\"uint256\"}],\"internalType\":\"structReportData\",\"name\":\"report\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"attestationTimestamp\",\"type\":\"uint256\"}],\"internalType\":\"structOracleAttestationData\",\"name\":\"_attestData\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"power\",\"type\":\"uint256\"}],\"internalType\":\"structValidator[]\",\"name\":\"_valset\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structSignature[]\",\"name\":\"_sigs\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"_depositId\",\"type\":\"uint256\"}],\"name\":\"withdrawFromLayer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"withdrawalClaimed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60a060405260405180602001604052805f815250604051602001620000259190620001f9565b60405160208183030381529060405260405160200162000046919062000279565b604051602081830303815290604052805190602001205f55600560809081525034801562000072575f80fd5b5060405162003b7a38038062003b7a833981810160405281019062000098919062000315565b80838160025f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050508160035f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050506200036e565b5f81519050919050565b5f82825260208201905092915050565b5f5b838110156200019e57808201518184015260208101905062000181565b5f8484015250505050565b5f601f19601f8301169050919050565b5f620001c58262000165565b620001d181856200016f565b9350620001e38185602086016200017f565b620001ee81620001a9565b840191505092915050565b5f6020820190508181035f830152620002138184620001b9565b905092915050565b5f82825260208201905092915050565b7f54656c6c6f724f7261636c6541646472657373000000000000000000000000005f82015250565b5f620002616013836200021b565b91506200026e826200022b565b602082019050919050565b5f6040820190508181035f830152620002928162000253565b90508181036020830152620002a88184620001b9565b905092915050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f620002df82620002b4565b9050919050565b620002f181620002d3565b8114620002fc575f80fd5b50565b5f815190506200030f81620002e6565b92915050565b5f805f606084860312156200032f576200032e620002b0565b5b5f6200033e86828701620002ff565b93505060206200035186828701620002ff565b92505060406200036486828701620002ff565b9150509250925092565b6080516137e5620003955f395f8181610c3a015281816115a30152611b7401526137e55ff3fe608060405234801561000f575f80fd5b5060043610610156575f3560e01c8063c0f95d52116100c1578063e78cea921161007a578063e78cea9214610419578063ecf7085814610437578063f4913c7e14610455578063fa3c06d214610471578063fc0c546a1461048f578063fc735e99146104ad57610156565b8063c0f95d5214610345578063ce5e11bf14610363578063d9c51cd414610393578063e07c5486146103af578063e513730b146103df578063e5d8b9dc146103fd57610156565b806377b03e0d1161011357806377b03e0d146102555780639410e01f146102855780639852099c146102a3578063a792765f146102c1578063b02c43d0146102f3578063b8eed2631461032757610156565b80631d8218541461015a5780631e8683341461018a578063285bbd48146101ba57806329449085146101d657806344e87f9114610207578063604f918f14610237575b5f80fd5b610174600480360381019061016f9190611bf9565b6104cb565b6040516101819190611c3e565b60405180910390f35b6101a4600480360381019061019f9190611cb1565b6104e8565b6040516101b19190611ceb565b60405180910390f35b6101d460048036038101906101cf9190611cb1565b6104fd565b005b6101f060048036038101906101eb9190611d37565b61087d565b6040516101fe929190611d75565b60405180910390f35b610221600480360381019061021c9190611d37565b610924565b60405161022e9190611c3e565b60405180910390f35b61023f6109c8565b60405161024c9190611ceb565b60405180910390f35b61026f600480360381019061026a9190611d9c565b6109ce565b60405161027c9190611ceb565b60405180910390f35b61028d610a6f565b60405161029a9190611ceb565b60405180910390f35b6102ab610a75565b6040516102b89190611ceb565b60405180910390f35b6102db60048036038101906102d69190611d37565b610a7b565b6040516102ea93929190611e51565b60405180910390f35b61030d60048036038101906103089190611bf9565b610b61565b60405161031e959493929190611eee565b60405180910390f35b61032f610c38565b60405161033c9190611ceb565b60405180910390f35b61034d610c5c565b60405161035a9190611ceb565b60405180910390f35b61037d60048036038101906103789190611d37565b610cf0565b60405161038a9190611ceb565b60405180910390f35b6103ad60048036038101906103a89190611bf9565b610d94565b005b6103c960048036038101906103c49190611d37565b610e36565b6040516103d69190611f46565b60405180910390f35b6103e7610eda565b6040516103f49190611fba565b60405180910390f35b610417600480360381019061041291906120ab565b610eff565b005b610421611564565b60405161042e919061218a565b60405180910390f35b61043f611589565b60405161044c9190611ceb565b60405180910390f35b61046f600480360381019061046a91906122cb565b611675565b005b610479611961565b6040516104869190611ceb565b60405180910390f35b610497611967565b6040516104a49190612357565b60405180910390f35b6104b561198c565b6040516104c29190611ceb565b60405180910390f35b6007602052805f5260405f205f915054906101000a900460ff1681565b6008602052805f5260405f205f915090505481565b5f60085f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490505f8111610580576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610577906123ba565b60405180910390fd5b5f610589611995565b90505f81116105cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105c490612448565b60405180910390fd5b81811015610742578060085f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205461061e9190612493565b60085f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f208190555080915060015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846040518363ffffffff1660e01b81526004016106be9291906124c6565b6020604051808303815f875af11580156106da573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106fe9190612517565b61073d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107349061258c565b60405180910390fd5b610860565b5f60085f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f208190555060015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846040518363ffffffff1660e01b81526004016107e09291906124c6565b6020604051808303815f875af11580156107fc573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108209190612517565b61085f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108569061258c565b60405180910390fd5b5b8160065f8282546108719190612493565b92505081905550505050565b5f8060025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632944908585856040518363ffffffff1660e01b81526004016108db9291906125b9565b6040805180830381865afa1580156108f5573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061091991906125f4565b915091509250929050565b5f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166344e87f9184846040518363ffffffff1660e01b81526004016109819291906125b9565b602060405180830381865afa15801561099c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109c09190612517565b905092915050565b61a8c081565b5f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166377b03e0d836040518263ffffffff1660e01b8152600401610a299190612632565b602060405180830381865afa158015610a44573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a68919061264b565b9050919050565b60065481565b60045481565b5f60605f80548503610ab557600130604051602001610a9a9190611f46565b60405160208183030381529060405242925092509250610b5a565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a792765f86866040518363ffffffff1660e01b8152600401610b119291906125b9565b5f60405180830381865afa158015610b2b573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190610b539190612714565b9250925092505b9250925092565b6009602052805f5260405f205f91509050805f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806001018054610ba5906127ad565b80601f0160208091040260200160405190810160405280929190818152602001828054610bd1906127ad565b8015610c1c5780601f10610bf357610100808354040283529160200191610c1c565b820191905f5260205f20905b815481529060010190602001808311610bff57829003601f168201915b5050505050908060020154908060030154908060040154905085565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c0f95d526040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cc7573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ceb919061264b565b905090565b5f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ce5e11bf84846040518363ffffffff1660e01b8152600401610d4d9291906125b9565b602060405180830381865afa158015610d68573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d8c919061264b565b905092915050565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330846040518463ffffffff1660e01b8152600401610df2939291906127dd565b6020604051808303815f875af1158015610e0e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e329190612517565b5050565b5f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e07c548684846040518363ffffffff1660e01b8152600401610e939291906125b9565b602060405180830381865afa158015610eae573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ed29190612826565b905092915050565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f81604051602001610f12929190611d75565b604051602081830303815290604052604051602001610f31919061289b565b60405160208183030381529060405280519060200120865f013514610f8b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8290612918565b60405180910390fd5b60075f8281526020019081526020015f205f9054906101000a900460ff1615610fe9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fe0906129a6565b60405180910390fd5b61a8c06103e8878060200190610fff91906129d0565b6020013561100d9190612a24565b426110189190612493565b11611058576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161104f90612ac4565b60405180910390fd5b61a8c06103e8876040013561106d9190612a24565b426110789190612493565b106110b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110af90612b2c565b60405180910390fd5b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635121b26e87878787876040518663ffffffff1660e01b815260040161111a959493929190612fbe565b5f6040518083038186803b158015611130575f80fd5b505afa158015611142573d5f803e3d5ffd5b5050505060035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ba95ec276040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111b0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111d4919061264b565b8680602001906111e491906129d0565b604001351015611229576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611220906130a2565b60405180910390fd5b600160075f8381526020019081526020015f205f6101000a81548160ff0219169083151502179055505f805f88806020019061126591906129d0565b805f019061127391906130c0565b810190611280919061315d565b509250925092505f64e8d4a510008261129991906131dd565b90505f6112a4611995565b9050818110156114265780826112ba9190612493565b60085f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054611302919061321e565b60085f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f208190555080915060015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb86846040518363ffffffff1660e01b81526004016113a29291906124c6565b6020604051808303815f875af11580156113be573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113e29190612517565b611421576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114189061258c565b60405180910390fd5b611502565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb86846040518363ffffffff1660e01b81526004016114829291906124c6565b6020604051808303815f875af115801561149e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114c29190612517565b611501576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114f89061258c565b60405180910390fd5b5b8160065f8282546115139190612493565b925050819055507f1c25a916bf61b55f3abb9060e620d13d6937f8c2ab2b7a16be824ffde44acb2f8685878560405161154f9493929190613251565b60405180910390a15050505050505050505050565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f61a8c06005544261159b9190612493565b111561166c577f000000000000000000000000000000000000000000000000000000000000000060015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161161c9190611f46565b602060405180830381865afa158015611637573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061165b919061264b565b6116659190612a24565b9050611672565b60065490505b90565b5f83116116b7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ae9061330b565b60405180910390fd5b6116bf611995565b831115611701576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116f890613399565b60405180910390fd5b82821115611744576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161173b90613427565b60405180910390fd5b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330866040518463ffffffff1660e01b81526004016117a2939291906127dd565b6020604051808303815f875af11580156117be573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117e29190612517565b611821576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118189061348f565b60405180910390fd5b60045f815480929190611833906134ad565b91905055508260065f8282546118499190612493565b925050819055506040518060a001604052803373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020018481526020018381526020014381525060095f60045481526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010190816118f99190613688565b506040820151816002015560608201518160030155608082015181600401559050507fe9a436e6735e7a54b0d2505d14247a614f3af68dad813a7a46834b876b13d7c160045433838686604051611954959493929190613757565b60405180910390a1505050565b60055481565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f61270f905090565b5f61a8c0600554426119a79190612493565b1115611bad575f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611a089190611f46565b602060405180830381865afa158015611a23573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a47919061264b565b905068056bc75e2d63100000811015611b725760015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b67f8cbd6040518163ffffffff1660e01b81526004015f604051808303815f87803b158015611ac0575f80fd5b505af1158015611ad2573d5f803e3d5ffd5b5050505060015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611b309190611f46565b602060405180830381865afa158015611b4b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b6f919061264b565b90505b7f000000000000000000000000000000000000000000000000000000000000000081611b9e9190612a24565b60068190555042600581905550505b600654905090565b5f604051905090565b5f80fd5b5f80fd5b5f819050919050565b611bd881611bc6565b8114611be2575f80fd5b50565b5f81359050611bf381611bcf565b92915050565b5f60208284031215611c0e57611c0d611bbe565b5b5f611c1b84828501611be5565b91505092915050565b5f8115159050919050565b611c3881611c24565b82525050565b5f602082019050611c515f830184611c2f565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611c8082611c57565b9050919050565b611c9081611c76565b8114611c9a575f80fd5b50565b5f81359050611cab81611c87565b92915050565b5f60208284031215611cc657611cc5611bbe565b5b5f611cd384828501611c9d565b91505092915050565b611ce581611bc6565b82525050565b5f602082019050611cfe5f830184611cdc565b92915050565b5f819050919050565b611d1681611d04565b8114611d20575f80fd5b50565b5f81359050611d3181611d0d565b92915050565b5f8060408385031215611d4d57611d4c611bbe565b5b5f611d5a85828601611d23565b9250506020611d6b85828601611be5565b9150509250929050565b5f604082019050611d885f830185611c2f565b611d956020830184611cdc565b9392505050565b5f60208284031215611db157611db0611bbe565b5b5f611dbe84828501611d23565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015611dfe578082015181840152602081019050611de3565b5f8484015250505050565b5f601f19601f8301169050919050565b5f611e2382611dc7565b611e2d8185611dd1565b9350611e3d818560208601611de1565b611e4681611e09565b840191505092915050565b5f606082019050611e645f830186611c2f565b8181036020830152611e768185611e19565b9050611e856040830184611cdc565b949350505050565b611e9681611c76565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f611ec082611e9c565b611eca8185611ea6565b9350611eda818560208601611de1565b611ee381611e09565b840191505092915050565b5f60a082019050611f015f830188611e8d565b8181036020830152611f138187611eb6565b9050611f226040830186611cdc565b611f2f6060830185611cdc565b611f3c6080830184611cdc565b9695505050505050565b5f602082019050611f595f830184611e8d565b92915050565b5f819050919050565b5f611f82611f7d611f7884611c57565b611f5f565b611c57565b9050919050565b5f611f9382611f68565b9050919050565b5f611fa482611f89565b9050919050565b611fb481611f9a565b82525050565b5f602082019050611fcd5f830184611fab565b92915050565b5f80fd5b5f60608284031215611fec57611feb611fd3565b5b81905092915050565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261201657612015611ff5565b5b8235905067ffffffffffffffff81111561203357612032611ff9565b5b60208301915083604082028301111561204f5761204e611ffd565b5b9250929050565b5f8083601f84011261206b5761206a611ff5565b5b8235905067ffffffffffffffff81111561208857612087611ff9565b5b6020830191508360608202830111156120a4576120a3611ffd565b5b9250929050565b5f805f805f80608087890312156120c5576120c4611bbe565b5b5f87013567ffffffffffffffff8111156120e2576120e1611bc2565b5b6120ee89828a01611fd7565b965050602087013567ffffffffffffffff81111561210f5761210e611bc2565b5b61211b89828a01612001565b9550955050604087013567ffffffffffffffff81111561213e5761213d611bc2565b5b61214a89828a01612056565b9350935050606061215d89828a01611be5565b9150509295509295509295565b5f61217482611f89565b9050919050565b6121848161216a565b82525050565b5f60208201905061219d5f83018461217b565b92915050565b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6121dd82611e09565b810181811067ffffffffffffffff821117156121fc576121fb6121a7565b5b80604052505050565b5f61220e611bb5565b905061221a82826121d4565b919050565b5f67ffffffffffffffff821115612239576122386121a7565b5b61224282611e09565b9050602081019050919050565b828183375f83830152505050565b5f61226f61226a8461221f565b612205565b90508281526020810184848401111561228b5761228a6121a3565b5b61229684828561224f565b509392505050565b5f82601f8301126122b2576122b1611ff5565b5b81356122c284826020860161225d565b91505092915050565b5f805f606084860312156122e2576122e1611bbe565b5b5f6122ef86828701611be5565b935050602061230086828701611be5565b925050604084013567ffffffffffffffff81111561232157612320611bc2565b5b61232d8682870161229e565b9150509250925092565b5f61234182611f89565b9050919050565b61235181612337565b82525050565b5f60208201905061236a5f830184612348565b92915050565b7f616d6f756e74206d757374206265203e203000000000000000000000000000005f82015250565b5f6123a4601283611ea6565b91506123af82612370565b602082019050919050565b5f6020820190508181035f8301526123d181612398565b9050919050565b7f546f6b656e4272696467653a206465706f7369744c696d6974206d75737420625f8201527f65203e2030000000000000000000000000000000000000000000000000000000602082015250565b5f612432602583611ea6565b915061243d826123d8565b604082019050919050565b5f6020820190508181035f83015261245f81612426565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61249d82611bc6565b91506124a883611bc6565b92508282039050818111156124c0576124bf612466565b5b92915050565b5f6040820190506124d95f830185611e8d565b6124e66020830184611cdc565b9392505050565b6124f681611c24565b8114612500575f80fd5b50565b5f81519050612511816124ed565b92915050565b5f6020828403121561252c5761252b611bbe565b5b5f61253984828501612503565b91505092915050565b7f546f6b656e4272696467653a207472616e73666572206661696c6564000000005f82015250565b5f612576601c83611ea6565b915061258182612542565b602082019050919050565b5f6020820190508181035f8301526125a38161256a565b9050919050565b6125b381611d04565b82525050565b5f6040820190506125cc5f8301856125aa565b6125d96020830184611cdc565b9392505050565b5f815190506125ee81611bcf565b92915050565b5f806040838503121561260a57612609611bbe565b5b5f61261785828601612503565b9250506020612628858286016125e0565b9150509250929050565b5f6020820190506126455f8301846125aa565b92915050565b5f602082840312156126605761265f611bbe565b5b5f61266d848285016125e0565b91505092915050565b5f67ffffffffffffffff8211156126905761268f6121a7565b5b61269982611e09565b9050602081019050919050565b5f6126b86126b384612676565b612205565b9050828152602081018484840111156126d4576126d36121a3565b5b6126df848285611de1565b509392505050565b5f82601f8301126126fb576126fa611ff5565b5b815161270b8482602086016126a6565b91505092915050565b5f805f6060848603121561272b5761272a611bbe565b5b5f61273886828701612503565b935050602084015167ffffffffffffffff81111561275957612758611bc2565b5b612765868287016126e7565b9250506040612776868287016125e0565b9150509250925092565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806127c457607f821691505b6020821081036127d7576127d6612780565b5b50919050565b5f6060820190506127f05f830186611e8d565b6127fd6020830185611e8d565b61280a6040830184611cdc565b949350505050565b5f8151905061282081611c87565b92915050565b5f6020828403121561283b5761283a611bbe565b5b5f61284884828501612812565b91505092915050565b7f54524242726964676500000000000000000000000000000000000000000000005f82015250565b5f612885600983611ea6565b915061289082612851565b602082019050919050565b5f6040820190508181035f8301526128b281612879565b905081810360208301526128c68184611e19565b905092915050565b7f546f6b656e4272696467653a20696e76616c69642071756572794964000000005f82015250565b5f612902601c83611ea6565b915061290d826128ce565b602082019050919050565b5f6020820190508181035f83015261292f816128f6565b9050919050565b7f546f6b656e4272696467653a207769746864726177616c20616c7265616479205f8201527f636c61696d656400000000000000000000000000000000000000000000000000602082015250565b5f612990602783611ea6565b915061299b82612936565b604082019050919050565b5f6020820190508181035f8301526129bd81612984565b9050919050565b5f80fd5b5f80fd5b5f80fd5b5f8235600160a0038336030381126129eb576129ea6129c4565b5b80830191505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f612a2e82611bc6565b9150612a3983611bc6565b925082612a4957612a486129f7565b5b828204905092915050565b7f546f6b656e4272696467653a207072656d6174757265206174746573746174695f8201527f6f6e000000000000000000000000000000000000000000000000000000000000602082015250565b5f612aae602283611ea6565b9150612ab982612a54565b604082019050919050565b5f6020820190508181035f830152612adb81612aa2565b9050919050565b7f546f6b656e4272696467653a206174746573746174696f6e20746f6f206f6c645f82015250565b5f612b16602083611ea6565b9150612b2182612ae2565b602082019050919050565b5f6020820190508181035f830152612b4381612b0a565b9050919050565b5f612b586020840184611d23565b905092915050565b612b6981611d04565b82525050565b5f80fd5b5f8235600160a003833603038112612b8e57612b8d612b6f565b5b82810191505092915050565b5f80fd5b5f80fd5b5f8083356001602003843603038112612bbe57612bbd612b6f565b5b83810192508235915060208301925067ffffffffffffffff821115612be657612be5612b9a565b5b600182023603831315612bfc57612bfb612b9e565b5b509250929050565b5f82825260208201905092915050565b5f612c1f8385612c04565b9350612c2c83858461224f565b612c3583611e09565b840190509392505050565b5f612c4e6020840184611be5565b905092915050565b612c5f81611bc6565b82525050565b5f60a08301612c765f840184612ba2565b8583035f870152612c88838284612c14565b92505050612c996020840184612c40565b612ca66020860182612c56565b50612cb46040840184612c40565b612cc16040860182612c56565b50612ccf6060840184612c40565b612cdc6060860182612c56565b50612cea6080840184612c40565b612cf76080860182612c56565b508091505092915050565b5f60608301612d135f840184612b4a565b612d1f5f860182612b60565b50612d2d6020840184612b73565b8482036020860152612d3f8282612c65565b915050612d4f6040840184612c40565b612d5c6040860182612c56565b508091505092915050565b5f82825260208201905092915050565b5f819050919050565b5f612d8e6020840184611c9d565b905092915050565b612d9f81611c76565b82525050565b60408201612db55f830183612d80565b612dc15f850182612d96565b50612dcf6020830183612c40565b612ddc6020850182612c56565b50505050565b5f612ded8383612da5565b60408301905092915050565b5f82905092915050565b5f604082019050919050565b5f612e1a8385612d67565b9350612e2582612d77565b805f5b85811015612e5d57612e3a8284612df9565b612e448882612de2565b9750612e4f83612e03565b925050600181019050612e28565b5085925050509392505050565b5f82825260208201905092915050565b5f819050919050565b5f60ff82169050919050565b612e9881612e83565b8114612ea2575f80fd5b50565b5f81359050612eb381612e8f565b92915050565b5f612ec76020840184612ea5565b905092915050565b612ed881612e83565b82525050565b60608201612eee5f830183612eb9565b612efa5f850182612ecf565b50612f086020830183612b4a565b612f156020850182612b60565b50612f236040830183612b4a565b612f306040850182612b60565b50505050565b5f612f418383612ede565b60608301905092915050565b5f82905092915050565b5f606082019050919050565b5f612f6e8385612e6a565b9350612f7982612e7a565b805f5b85811015612fb157612f8e8284612f4d565b612f988882612f36565b9750612fa383612f57565b925050600181019050612f7c565b5085925050509392505050565b5f6060820190508181035f830152612fd68188612d02565b90508181036020830152612feb818688612e0f565b90508181036040830152613000818486612f63565b90509695505050505050565b7f5265706f72742061676772656761746520706f776572206d75737420626520675f8201527f726561746572207468616e206f7220657175616c20746f205f6d696e696d756d60208201527f506f776572000000000000000000000000000000000000000000000000000000604082015250565b5f61308c604583611ea6565b91506130978261300c565b606082019050919050565b5f6020820190508181035f8301526130b981613080565b9050919050565b5f80833560016020038436030381126130dc576130db6129c4565b5b80840192508235915067ffffffffffffffff8211156130fe576130fd6129c8565b5b60208301925060018202360383131561311a576131196129cc565b5b509250929050565b5f61312c82611c57565b9050919050565b61313c81613122565b8114613146575f80fd5b50565b5f8135905061315781613133565b92915050565b5f805f806080858703121561317557613174611bbe565b5b5f61318287828801613149565b945050602085013567ffffffffffffffff8111156131a3576131a2611bc2565b5b6131af8782880161229e565b93505060406131c087828801611be5565b92505060606131d187828801611be5565b91505092959194509250565b5f6131e782611bc6565b91506131f283611bc6565b925082820261320081611bc6565b9150828204841483151761321757613216612466565b5b5092915050565b5f61322882611bc6565b915061323383611bc6565b925082820190508082111561324b5761324a612466565b5b92915050565b5f6080820190506132645f830187611cdc565b81810360208301526132768186611eb6565b90506132856040830185611e8d565b6132926060830184611cdc565b95945050505050565b7f546f6b656e4272696467653a20616d6f756e74206d75737420626520677265615f8201527f746572207468616e203000000000000000000000000000000000000000000000602082015250565b5f6132f5602a83611ea6565b91506133008261329b565b604082019050919050565b5f6020820190508181035f830152613322816132e9565b9050919050565b7f546f6b656e4272696467653a20616d6f756e742065786365656473206465706f5f8201527f736974206c696d697420666f722074696d6520706572696f6400000000000000602082015250565b5f613383603983611ea6565b915061338e82613329565b604082019050919050565b5f6020820190508181035f8301526133b081613377565b9050919050565b7f546f6b656e4272696467653a20746970206d757374206265206c6573732074685f8201527f616e206f7220657175616c20746f20616d6f756e740000000000000000000000602082015250565b5f613411603583611ea6565b915061341c826133b7565b604082019050919050565b5f6020820190508181035f83015261343e81613405565b9050919050565b7f546f6b656e4272696467653a207472616e7366657246726f6d206661696c65645f82015250565b5f613479602083611ea6565b915061348482613445565b602082019050919050565b5f6020820190508181035f8301526134a68161346d565b9050919050565b5f6134b782611bc6565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036134e9576134e8612466565b5b600182019050919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026135507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613515565b61355a8683613515565b95508019841693508086168417925050509392505050565b5f61358c61358761358284611bc6565b611f5f565b611bc6565b9050919050565b5f819050919050565b6135a583613572565b6135b96135b182613593565b848454613521565b825550505050565b5f90565b6135cd6135c1565b6135d881848461359c565b505050565b5b818110156135fb576135f05f826135c5565b6001810190506135de565b5050565b601f82111561364057613611816134f4565b61361a84613506565b81016020851015613629578190505b61363d61363585613506565b8301826135dd565b50505b505050565b5f82821c905092915050565b5f6136605f1984600802613645565b1980831691505092915050565b5f6136788383613651565b9150826002028217905092915050565b61369182611e9c565b67ffffffffffffffff8111156136aa576136a96121a7565b5b6136b482546127ad565b6136bf8282856135ff565b5f60209050601f8311600181146136f0575f84156136de578287015190505b6136e8858261366d565b86555061374f565b601f1984166136fe866134f4565b5f5b8281101561372557848901518255600182019150602085019450602081019050613700565b86831015613742578489015161373e601f891682613651565b8355505b6001600288020188555050505b505050505050565b5f60a08201905061376a5f830188611cdc565b6137776020830187611e8d565b81810360408301526137898186611eb6565b90506137986060830185611cdc565b6137a56080830184611cdc565b969550505050505056fea2646970667358221220ac3dd7dffa2da8b3fd2c77ccf98545f69c265e46a14d92e5fea4dbeab9804d1764736f6c63430008160033", } // TokenBridgeABI is the input ABI used to generate the binding from. @@ -73,7 +73,7 @@ var TokenBridgeABI = TokenBridgeMetaData.ABI var TokenBridgeBin = TokenBridgeMetaData.Bin // DeployTokenBridge deploys a new Ethereum contract, binding an instance of TokenBridge to it. -func DeployTokenBridge(auth *bind.TransactOpts, backend bind.ContractBackend, _token common.Address, _blobstream common.Address) (common.Address, *types.Transaction, *TokenBridge, error) { +func DeployTokenBridge(auth *bind.TransactOpts, backend bind.ContractBackend, _token common.Address, _blobstream common.Address, _tellorFlex common.Address) (common.Address, *types.Transaction, *TokenBridge, error) { parsed, err := TokenBridgeMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -82,7 +82,7 @@ func DeployTokenBridge(auth *bind.TransactOpts, backend bind.ContractBackend, _t return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TokenBridgeBin), backend, _token, _blobstream) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TokenBridgeBin), backend, _token, _blobstream, _tellorFlex) if err != nil { return common.Address{}, nil, nil, err } @@ -231,12 +231,12 @@ func (_TokenBridge *TokenBridgeTransactorRaw) Transact(opts *bind.TransactOpts, return _TokenBridge.Contract.contract.Transact(opts, method, params...) } -// DEPOSITLIMITPERCENTAGE is a free data retrieval call binding the contract method 0xe2f8b4b5. +// DEPOSITLIMITDENOMINATOR is a free data retrieval call binding the contract method 0xb8eed263. // -// Solidity: function DEPOSIT_LIMIT_PERCENTAGE() view returns(uint256) -func (_TokenBridge *TokenBridgeCaller) DEPOSITLIMITPERCENTAGE(opts *bind.CallOpts) (*big.Int, error) { +// Solidity: function DEPOSIT_LIMIT_DENOMINATOR() view returns(uint256) +func (_TokenBridge *TokenBridgeCaller) DEPOSITLIMITDENOMINATOR(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _TokenBridge.contract.Call(opts, &out, "DEPOSIT_LIMIT_PERCENTAGE") + err := _TokenBridge.contract.Call(opts, &out, "DEPOSIT_LIMIT_DENOMINATOR") if err != nil { return *new(*big.Int), err @@ -248,18 +248,18 @@ func (_TokenBridge *TokenBridgeCaller) DEPOSITLIMITPERCENTAGE(opts *bind.CallOpt } -// DEPOSITLIMITPERCENTAGE is a free data retrieval call binding the contract method 0xe2f8b4b5. +// DEPOSITLIMITDENOMINATOR is a free data retrieval call binding the contract method 0xb8eed263. // -// Solidity: function DEPOSIT_LIMIT_PERCENTAGE() view returns(uint256) -func (_TokenBridge *TokenBridgeSession) DEPOSITLIMITPERCENTAGE() (*big.Int, error) { - return _TokenBridge.Contract.DEPOSITLIMITPERCENTAGE(&_TokenBridge.CallOpts) +// Solidity: function DEPOSIT_LIMIT_DENOMINATOR() view returns(uint256) +func (_TokenBridge *TokenBridgeSession) DEPOSITLIMITDENOMINATOR() (*big.Int, error) { + return _TokenBridge.Contract.DEPOSITLIMITDENOMINATOR(&_TokenBridge.CallOpts) } -// DEPOSITLIMITPERCENTAGE is a free data retrieval call binding the contract method 0xe2f8b4b5. +// DEPOSITLIMITDENOMINATOR is a free data retrieval call binding the contract method 0xb8eed263. // -// Solidity: function DEPOSIT_LIMIT_PERCENTAGE() view returns(uint256) -func (_TokenBridge *TokenBridgeCallerSession) DEPOSITLIMITPERCENTAGE() (*big.Int, error) { - return _TokenBridge.Contract.DEPOSITLIMITPERCENTAGE(&_TokenBridge.CallOpts) +// Solidity: function DEPOSIT_LIMIT_DENOMINATOR() view returns(uint256) +func (_TokenBridge *TokenBridgeCallerSession) DEPOSITLIMITDENOMINATOR() (*big.Int, error) { + return _TokenBridge.Contract.DEPOSITLIMITDENOMINATOR(&_TokenBridge.CallOpts) } // DEPOSITLIMITUPDATEINTERVAL is a free data retrieval call binding the contract method 0x604f918f. @@ -293,74 +293,74 @@ func (_TokenBridge *TokenBridgeCallerSession) DEPOSITLIMITUPDATEINTERVAL() (*big return _TokenBridge.Contract.DEPOSITLIMITUPDATEINTERVAL(&_TokenBridge.CallOpts) } -// MAXATTESTATIONAGE is a free data retrieval call binding the contract method 0xb9f7bb8d. +// Bridge is a free data retrieval call binding the contract method 0xe78cea92. // -// Solidity: function MAX_ATTESTATION_AGE() view returns(uint256) -func (_TokenBridge *TokenBridgeCaller) MAXATTESTATIONAGE(opts *bind.CallOpts) (*big.Int, error) { +// Solidity: function bridge() view returns(address) +func (_TokenBridge *TokenBridgeCaller) Bridge(opts *bind.CallOpts) (common.Address, error) { var out []interface{} - err := _TokenBridge.contract.Call(opts, &out, "MAX_ATTESTATION_AGE") + err := _TokenBridge.contract.Call(opts, &out, "bridge") if err != nil { - return *new(*big.Int), err + return *new(common.Address), err } - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) return out0, err } -// MAXATTESTATIONAGE is a free data retrieval call binding the contract method 0xb9f7bb8d. +// Bridge is a free data retrieval call binding the contract method 0xe78cea92. // -// Solidity: function MAX_ATTESTATION_AGE() view returns(uint256) -func (_TokenBridge *TokenBridgeSession) MAXATTESTATIONAGE() (*big.Int, error) { - return _TokenBridge.Contract.MAXATTESTATIONAGE(&_TokenBridge.CallOpts) +// Solidity: function bridge() view returns(address) +func (_TokenBridge *TokenBridgeSession) Bridge() (common.Address, error) { + return _TokenBridge.Contract.Bridge(&_TokenBridge.CallOpts) } -// MAXATTESTATIONAGE is a free data retrieval call binding the contract method 0xb9f7bb8d. +// Bridge is a free data retrieval call binding the contract method 0xe78cea92. // -// Solidity: function MAX_ATTESTATION_AGE() view returns(uint256) -func (_TokenBridge *TokenBridgeCallerSession) MAXATTESTATIONAGE() (*big.Int, error) { - return _TokenBridge.Contract.MAXATTESTATIONAGE(&_TokenBridge.CallOpts) +// Solidity: function bridge() view returns(address) +func (_TokenBridge *TokenBridgeCallerSession) Bridge() (common.Address, error) { + return _TokenBridge.Contract.Bridge(&_TokenBridge.CallOpts) } -// Bridge is a free data retrieval call binding the contract method 0xe78cea92. +// DepositId is a free data retrieval call binding the contract method 0x9852099c. // -// Solidity: function bridge() view returns(address) -func (_TokenBridge *TokenBridgeCaller) Bridge(opts *bind.CallOpts) (common.Address, error) { +// Solidity: function depositId() view returns(uint256) +func (_TokenBridge *TokenBridgeCaller) DepositId(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _TokenBridge.contract.Call(opts, &out, "bridge") + err := _TokenBridge.contract.Call(opts, &out, "depositId") if err != nil { - return *new(common.Address), err + return *new(*big.Int), err } - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) return out0, err } -// Bridge is a free data retrieval call binding the contract method 0xe78cea92. +// DepositId is a free data retrieval call binding the contract method 0x9852099c. // -// Solidity: function bridge() view returns(address) -func (_TokenBridge *TokenBridgeSession) Bridge() (common.Address, error) { - return _TokenBridge.Contract.Bridge(&_TokenBridge.CallOpts) +// Solidity: function depositId() view returns(uint256) +func (_TokenBridge *TokenBridgeSession) DepositId() (*big.Int, error) { + return _TokenBridge.Contract.DepositId(&_TokenBridge.CallOpts) } -// Bridge is a free data retrieval call binding the contract method 0xe78cea92. +// DepositId is a free data retrieval call binding the contract method 0x9852099c. // -// Solidity: function bridge() view returns(address) -func (_TokenBridge *TokenBridgeCallerSession) Bridge() (common.Address, error) { - return _TokenBridge.Contract.Bridge(&_TokenBridge.CallOpts) +// Solidity: function depositId() view returns(uint256) +func (_TokenBridge *TokenBridgeCallerSession) DepositId() (*big.Int, error) { + return _TokenBridge.Contract.DepositId(&_TokenBridge.CallOpts) } -// CurrentDepositLimit is a free data retrieval call binding the contract method 0x0295d71b. +// DepositLimit is a free data retrieval call binding the contract method 0xecf70858. // -// Solidity: function currentDepositLimit() view returns(uint256) -func (_TokenBridge *TokenBridgeCaller) CurrentDepositLimit(opts *bind.CallOpts) (*big.Int, error) { +// Solidity: function depositLimit() view returns(uint256) +func (_TokenBridge *TokenBridgeCaller) DepositLimit(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _TokenBridge.contract.Call(opts, &out, "currentDepositLimit") + err := _TokenBridge.contract.Call(opts, &out, "depositLimit") if err != nil { return *new(*big.Int), err @@ -372,26 +372,26 @@ func (_TokenBridge *TokenBridgeCaller) CurrentDepositLimit(opts *bind.CallOpts) } -// CurrentDepositLimit is a free data retrieval call binding the contract method 0x0295d71b. +// DepositLimit is a free data retrieval call binding the contract method 0xecf70858. // -// Solidity: function currentDepositLimit() view returns(uint256) -func (_TokenBridge *TokenBridgeSession) CurrentDepositLimit() (*big.Int, error) { - return _TokenBridge.Contract.CurrentDepositLimit(&_TokenBridge.CallOpts) +// Solidity: function depositLimit() view returns(uint256) +func (_TokenBridge *TokenBridgeSession) DepositLimit() (*big.Int, error) { + return _TokenBridge.Contract.DepositLimit(&_TokenBridge.CallOpts) } -// CurrentDepositLimit is a free data retrieval call binding the contract method 0x0295d71b. +// DepositLimit is a free data retrieval call binding the contract method 0xecf70858. // -// Solidity: function currentDepositLimit() view returns(uint256) -func (_TokenBridge *TokenBridgeCallerSession) CurrentDepositLimit() (*big.Int, error) { - return _TokenBridge.Contract.CurrentDepositLimit(&_TokenBridge.CallOpts) +// Solidity: function depositLimit() view returns(uint256) +func (_TokenBridge *TokenBridgeCallerSession) DepositLimit() (*big.Int, error) { + return _TokenBridge.Contract.DepositLimit(&_TokenBridge.CallOpts) } -// DepositId is a free data retrieval call binding the contract method 0x9852099c. +// DepositLimitRecord is a free data retrieval call binding the contract method 0x9410e01f. // -// Solidity: function depositId() view returns(uint256) -func (_TokenBridge *TokenBridgeCaller) DepositId(opts *bind.CallOpts) (*big.Int, error) { +// Solidity: function depositLimitRecord() view returns(uint256) +func (_TokenBridge *TokenBridgeCaller) DepositLimitRecord(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _TokenBridge.contract.Call(opts, &out, "depositId") + err := _TokenBridge.contract.Call(opts, &out, "depositLimitRecord") if err != nil { return *new(*big.Int), err @@ -403,18 +403,18 @@ func (_TokenBridge *TokenBridgeCaller) DepositId(opts *bind.CallOpts) (*big.Int, } -// DepositId is a free data retrieval call binding the contract method 0x9852099c. +// DepositLimitRecord is a free data retrieval call binding the contract method 0x9410e01f. // -// Solidity: function depositId() view returns(uint256) -func (_TokenBridge *TokenBridgeSession) DepositId() (*big.Int, error) { - return _TokenBridge.Contract.DepositId(&_TokenBridge.CallOpts) +// Solidity: function depositLimitRecord() view returns(uint256) +func (_TokenBridge *TokenBridgeSession) DepositLimitRecord() (*big.Int, error) { + return _TokenBridge.Contract.DepositLimitRecord(&_TokenBridge.CallOpts) } -// DepositId is a free data retrieval call binding the contract method 0x9852099c. +// DepositLimitRecord is a free data retrieval call binding the contract method 0x9410e01f. // -// Solidity: function depositId() view returns(uint256) -func (_TokenBridge *TokenBridgeCallerSession) DepositId() (*big.Int, error) { - return _TokenBridge.Contract.DepositId(&_TokenBridge.CallOpts) +// Solidity: function depositLimitRecord() view returns(uint256) +func (_TokenBridge *TokenBridgeCallerSession) DepositLimitRecord() (*big.Int, error) { + return _TokenBridge.Contract.DepositLimitRecord(&_TokenBridge.CallOpts) } // DepositLimitUpdateTime is a free data retrieval call binding the contract method 0xfa3c06d2. @@ -450,11 +450,12 @@ func (_TokenBridge *TokenBridgeCallerSession) DepositLimitUpdateTime() (*big.Int // Deposits is a free data retrieval call binding the contract method 0xb02c43d0. // -// Solidity: function deposits(uint256 ) view returns(address sender, string recipient, uint256 amount, uint256 blockHeight) +// Solidity: function deposits(uint256 ) view returns(address sender, string recipient, uint256 amount, uint256 tip, uint256 blockHeight) func (_TokenBridge *TokenBridgeCaller) Deposits(opts *bind.CallOpts, arg0 *big.Int) (struct { Sender common.Address Recipient string Amount *big.Int + Tip *big.Int BlockHeight *big.Int }, error) { var out []interface{} @@ -464,6 +465,7 @@ func (_TokenBridge *TokenBridgeCaller) Deposits(opts *bind.CallOpts, arg0 *big.I Sender common.Address Recipient string Amount *big.Int + Tip *big.Int BlockHeight *big.Int }) if err != nil { @@ -473,7 +475,8 @@ func (_TokenBridge *TokenBridgeCaller) Deposits(opts *bind.CallOpts, arg0 *big.I outstruct.Sender = *abi.ConvertType(out[0], new(common.Address)).(*common.Address) outstruct.Recipient = *abi.ConvertType(out[1], new(string)).(*string) outstruct.Amount = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) - outstruct.BlockHeight = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) + outstruct.Tip = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) + outstruct.BlockHeight = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int) return *outstruct, err @@ -481,11 +484,12 @@ func (_TokenBridge *TokenBridgeCaller) Deposits(opts *bind.CallOpts, arg0 *big.I // Deposits is a free data retrieval call binding the contract method 0xb02c43d0. // -// Solidity: function deposits(uint256 ) view returns(address sender, string recipient, uint256 amount, uint256 blockHeight) +// Solidity: function deposits(uint256 ) view returns(address sender, string recipient, uint256 amount, uint256 tip, uint256 blockHeight) func (_TokenBridge *TokenBridgeSession) Deposits(arg0 *big.Int) (struct { Sender common.Address Recipient string Amount *big.Int + Tip *big.Int BlockHeight *big.Int }, error) { return _TokenBridge.Contract.Deposits(&_TokenBridge.CallOpts, arg0) @@ -493,146 +497,242 @@ func (_TokenBridge *TokenBridgeSession) Deposits(arg0 *big.Int) (struct { // Deposits is a free data retrieval call binding the contract method 0xb02c43d0. // -// Solidity: function deposits(uint256 ) view returns(address sender, string recipient, uint256 amount, uint256 blockHeight) +// Solidity: function deposits(uint256 ) view returns(address sender, string recipient, uint256 amount, uint256 tip, uint256 blockHeight) func (_TokenBridge *TokenBridgeCallerSession) Deposits(arg0 *big.Int) (struct { Sender common.Address Recipient string Amount *big.Int + Tip *big.Int BlockHeight *big.Int }, error) { return _TokenBridge.Contract.Deposits(&_TokenBridge.CallOpts, arg0) } -// GetDataWithFallback is a free data retrieval call binding the contract method 0x50b5c02d. +// GetDataBefore is a free data retrieval call binding the contract method 0xa792765f. // -// Solidity: function getDataWithFallback((bytes32,(bytes,uint256,uint256,uint256,uint256),uint256) _attest, (address,uint256)[] _currentValidatorSet, (uint8,bytes32,bytes32)[] _sigs, uint256 _fallbackTimestamp, uint256 _fallbackMinimumPower, uint256 _maxAttestationAge) view returns(bool) -func (_TokenBridge *TokenBridgeCaller) GetDataWithFallback(opts *bind.CallOpts, _attest OracleAttestationData, _currentValidatorSet []Validator, _sigs []Signature, _fallbackTimestamp *big.Int, _fallbackMinimumPower *big.Int, _maxAttestationAge *big.Int) (bool, error) { +// Solidity: function getDataBefore(bytes32 _queryId, uint256 _timestamp) view returns(bool _ifRetrieve, bytes _value, uint256 _timestampRetrieved) +func (_TokenBridge *TokenBridgeCaller) GetDataBefore(opts *bind.CallOpts, _queryId [32]byte, _timestamp *big.Int) (struct { + IfRetrieve bool + Value []byte + TimestampRetrieved *big.Int +}, error) { var out []interface{} - err := _TokenBridge.contract.Call(opts, &out, "getDataWithFallback", _attest, _currentValidatorSet, _sigs, _fallbackTimestamp, _fallbackMinimumPower, _maxAttestationAge) + err := _TokenBridge.contract.Call(opts, &out, "getDataBefore", _queryId, _timestamp) + outstruct := new(struct { + IfRetrieve bool + Value []byte + TimestampRetrieved *big.Int + }) if err != nil { - return *new(bool), err + return *outstruct, err } - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.IfRetrieve = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.Value = *abi.ConvertType(out[1], new([]byte)).(*[]byte) + outstruct.TimestampRetrieved = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +// GetDataBefore is a free data retrieval call binding the contract method 0xa792765f. +// +// Solidity: function getDataBefore(bytes32 _queryId, uint256 _timestamp) view returns(bool _ifRetrieve, bytes _value, uint256 _timestampRetrieved) +func (_TokenBridge *TokenBridgeSession) GetDataBefore(_queryId [32]byte, _timestamp *big.Int) (struct { + IfRetrieve bool + Value []byte + TimestampRetrieved *big.Int +}, error) { + return _TokenBridge.Contract.GetDataBefore(&_TokenBridge.CallOpts, _queryId, _timestamp) +} + +// GetDataBefore is a free data retrieval call binding the contract method 0xa792765f. +// +// Solidity: function getDataBefore(bytes32 _queryId, uint256 _timestamp) view returns(bool _ifRetrieve, bytes _value, uint256 _timestampRetrieved) +func (_TokenBridge *TokenBridgeCallerSession) GetDataBefore(_queryId [32]byte, _timestamp *big.Int) (struct { + IfRetrieve bool + Value []byte + TimestampRetrieved *big.Int +}, error) { + return _TokenBridge.Contract.GetDataBefore(&_TokenBridge.CallOpts, _queryId, _timestamp) +} + +// GetIndexForDataBefore is a free data retrieval call binding the contract method 0x29449085. +// +// Solidity: function getIndexForDataBefore(bytes32 _queryId, uint256 _timestamp) view returns(bool _found, uint256 _index) +func (_TokenBridge *TokenBridgeCaller) GetIndexForDataBefore(opts *bind.CallOpts, _queryId [32]byte, _timestamp *big.Int) (struct { + Found bool + Index *big.Int +}, error) { + var out []interface{} + err := _TokenBridge.contract.Call(opts, &out, "getIndexForDataBefore", _queryId, _timestamp) + + outstruct := new(struct { + Found bool + Index *big.Int + }) + if err != nil { + return *outstruct, err + } + + outstruct.Found = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.Index = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +// GetIndexForDataBefore is a free data retrieval call binding the contract method 0x29449085. +// +// Solidity: function getIndexForDataBefore(bytes32 _queryId, uint256 _timestamp) view returns(bool _found, uint256 _index) +func (_TokenBridge *TokenBridgeSession) GetIndexForDataBefore(_queryId [32]byte, _timestamp *big.Int) (struct { + Found bool + Index *big.Int +}, error) { + return _TokenBridge.Contract.GetIndexForDataBefore(&_TokenBridge.CallOpts, _queryId, _timestamp) +} + +// GetIndexForDataBefore is a free data retrieval call binding the contract method 0x29449085. +// +// Solidity: function getIndexForDataBefore(bytes32 _queryId, uint256 _timestamp) view returns(bool _found, uint256 _index) +func (_TokenBridge *TokenBridgeCallerSession) GetIndexForDataBefore(_queryId [32]byte, _timestamp *big.Int) (struct { + Found bool + Index *big.Int +}, error) { + return _TokenBridge.Contract.GetIndexForDataBefore(&_TokenBridge.CallOpts, _queryId, _timestamp) +} + +// GetNewValueCountbyQueryId is a free data retrieval call binding the contract method 0x77b03e0d. +// +// Solidity: function getNewValueCountbyQueryId(bytes32 _queryId) view returns(uint256) +func (_TokenBridge *TokenBridgeCaller) GetNewValueCountbyQueryId(opts *bind.CallOpts, _queryId [32]byte) (*big.Int, error) { + var out []interface{} + err := _TokenBridge.contract.Call(opts, &out, "getNewValueCountbyQueryId", _queryId) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) return out0, err } -// GetDataWithFallback is a free data retrieval call binding the contract method 0x50b5c02d. +// GetNewValueCountbyQueryId is a free data retrieval call binding the contract method 0x77b03e0d. // -// Solidity: function getDataWithFallback((bytes32,(bytes,uint256,uint256,uint256,uint256),uint256) _attest, (address,uint256)[] _currentValidatorSet, (uint8,bytes32,bytes32)[] _sigs, uint256 _fallbackTimestamp, uint256 _fallbackMinimumPower, uint256 _maxAttestationAge) view returns(bool) -func (_TokenBridge *TokenBridgeSession) GetDataWithFallback(_attest OracleAttestationData, _currentValidatorSet []Validator, _sigs []Signature, _fallbackTimestamp *big.Int, _fallbackMinimumPower *big.Int, _maxAttestationAge *big.Int) (bool, error) { - return _TokenBridge.Contract.GetDataWithFallback(&_TokenBridge.CallOpts, _attest, _currentValidatorSet, _sigs, _fallbackTimestamp, _fallbackMinimumPower, _maxAttestationAge) +// Solidity: function getNewValueCountbyQueryId(bytes32 _queryId) view returns(uint256) +func (_TokenBridge *TokenBridgeSession) GetNewValueCountbyQueryId(_queryId [32]byte) (*big.Int, error) { + return _TokenBridge.Contract.GetNewValueCountbyQueryId(&_TokenBridge.CallOpts, _queryId) } -// GetDataWithFallback is a free data retrieval call binding the contract method 0x50b5c02d. +// GetNewValueCountbyQueryId is a free data retrieval call binding the contract method 0x77b03e0d. // -// Solidity: function getDataWithFallback((bytes32,(bytes,uint256,uint256,uint256,uint256),uint256) _attest, (address,uint256)[] _currentValidatorSet, (uint8,bytes32,bytes32)[] _sigs, uint256 _fallbackTimestamp, uint256 _fallbackMinimumPower, uint256 _maxAttestationAge) view returns(bool) -func (_TokenBridge *TokenBridgeCallerSession) GetDataWithFallback(_attest OracleAttestationData, _currentValidatorSet []Validator, _sigs []Signature, _fallbackTimestamp *big.Int, _fallbackMinimumPower *big.Int, _maxAttestationAge *big.Int) (bool, error) { - return _TokenBridge.Contract.GetDataWithFallback(&_TokenBridge.CallOpts, _attest, _currentValidatorSet, _sigs, _fallbackTimestamp, _fallbackMinimumPower, _maxAttestationAge) +// Solidity: function getNewValueCountbyQueryId(bytes32 _queryId) view returns(uint256) +func (_TokenBridge *TokenBridgeCallerSession) GetNewValueCountbyQueryId(_queryId [32]byte) (*big.Int, error) { + return _TokenBridge.Contract.GetNewValueCountbyQueryId(&_TokenBridge.CallOpts, _queryId) } -// IsAnyConsensusValue is a free data retrieval call binding the contract method 0x0dc91aab. +// GetReporterByTimestamp is a free data retrieval call binding the contract method 0xe07c5486. // -// Solidity: function isAnyConsensusValue((bytes32,(bytes,uint256,uint256,uint256,uint256),uint256) _attest, (address,uint256)[] _currentValidatorSet, (uint8,bytes32,bytes32)[] _sigs, uint256 _maxAttestationAge) view returns(bool) -func (_TokenBridge *TokenBridgeCaller) IsAnyConsensusValue(opts *bind.CallOpts, _attest OracleAttestationData, _currentValidatorSet []Validator, _sigs []Signature, _maxAttestationAge *big.Int) (bool, error) { +// Solidity: function getReporterByTimestamp(bytes32 _queryId, uint256 _timestamp) view returns(address) +func (_TokenBridge *TokenBridgeCaller) GetReporterByTimestamp(opts *bind.CallOpts, _queryId [32]byte, _timestamp *big.Int) (common.Address, error) { var out []interface{} - err := _TokenBridge.contract.Call(opts, &out, "isAnyConsensusValue", _attest, _currentValidatorSet, _sigs, _maxAttestationAge) + err := _TokenBridge.contract.Call(opts, &out, "getReporterByTimestamp", _queryId, _timestamp) if err != nil { - return *new(bool), err + return *new(common.Address), err } - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) return out0, err } -// IsAnyConsensusValue is a free data retrieval call binding the contract method 0x0dc91aab. +// GetReporterByTimestamp is a free data retrieval call binding the contract method 0xe07c5486. // -// Solidity: function isAnyConsensusValue((bytes32,(bytes,uint256,uint256,uint256,uint256),uint256) _attest, (address,uint256)[] _currentValidatorSet, (uint8,bytes32,bytes32)[] _sigs, uint256 _maxAttestationAge) view returns(bool) -func (_TokenBridge *TokenBridgeSession) IsAnyConsensusValue(_attest OracleAttestationData, _currentValidatorSet []Validator, _sigs []Signature, _maxAttestationAge *big.Int) (bool, error) { - return _TokenBridge.Contract.IsAnyConsensusValue(&_TokenBridge.CallOpts, _attest, _currentValidatorSet, _sigs, _maxAttestationAge) +// Solidity: function getReporterByTimestamp(bytes32 _queryId, uint256 _timestamp) view returns(address) +func (_TokenBridge *TokenBridgeSession) GetReporterByTimestamp(_queryId [32]byte, _timestamp *big.Int) (common.Address, error) { + return _TokenBridge.Contract.GetReporterByTimestamp(&_TokenBridge.CallOpts, _queryId, _timestamp) } -// IsAnyConsensusValue is a free data retrieval call binding the contract method 0x0dc91aab. +// GetReporterByTimestamp is a free data retrieval call binding the contract method 0xe07c5486. // -// Solidity: function isAnyConsensusValue((bytes32,(bytes,uint256,uint256,uint256,uint256),uint256) _attest, (address,uint256)[] _currentValidatorSet, (uint8,bytes32,bytes32)[] _sigs, uint256 _maxAttestationAge) view returns(bool) -func (_TokenBridge *TokenBridgeCallerSession) IsAnyConsensusValue(_attest OracleAttestationData, _currentValidatorSet []Validator, _sigs []Signature, _maxAttestationAge *big.Int) (bool, error) { - return _TokenBridge.Contract.IsAnyConsensusValue(&_TokenBridge.CallOpts, _attest, _currentValidatorSet, _sigs, _maxAttestationAge) +// Solidity: function getReporterByTimestamp(bytes32 _queryId, uint256 _timestamp) view returns(address) +func (_TokenBridge *TokenBridgeCallerSession) GetReporterByTimestamp(_queryId [32]byte, _timestamp *big.Int) (common.Address, error) { + return _TokenBridge.Contract.GetReporterByTimestamp(&_TokenBridge.CallOpts, _queryId, _timestamp) } -// IsCurrentConsensusValue is a free data retrieval call binding the contract method 0x601319eb. +// GetTimeOfLastNewValue is a free data retrieval call binding the contract method 0xc0f95d52. // -// Solidity: function isCurrentConsensusValue((bytes32,(bytes,uint256,uint256,uint256,uint256),uint256) _attest, (address,uint256)[] _currentValidatorSet, (uint8,bytes32,bytes32)[] _sigs, uint256 _maxAttestationAge) view returns(bool) -func (_TokenBridge *TokenBridgeCaller) IsCurrentConsensusValue(opts *bind.CallOpts, _attest OracleAttestationData, _currentValidatorSet []Validator, _sigs []Signature, _maxAttestationAge *big.Int) (bool, error) { +// Solidity: function getTimeOfLastNewValue() view returns(uint256) +func (_TokenBridge *TokenBridgeCaller) GetTimeOfLastNewValue(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _TokenBridge.contract.Call(opts, &out, "isCurrentConsensusValue", _attest, _currentValidatorSet, _sigs, _maxAttestationAge) + err := _TokenBridge.contract.Call(opts, &out, "getTimeOfLastNewValue") if err != nil { - return *new(bool), err + return *new(*big.Int), err } - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) return out0, err } -// IsCurrentConsensusValue is a free data retrieval call binding the contract method 0x601319eb. +// GetTimeOfLastNewValue is a free data retrieval call binding the contract method 0xc0f95d52. // -// Solidity: function isCurrentConsensusValue((bytes32,(bytes,uint256,uint256,uint256,uint256),uint256) _attest, (address,uint256)[] _currentValidatorSet, (uint8,bytes32,bytes32)[] _sigs, uint256 _maxAttestationAge) view returns(bool) -func (_TokenBridge *TokenBridgeSession) IsCurrentConsensusValue(_attest OracleAttestationData, _currentValidatorSet []Validator, _sigs []Signature, _maxAttestationAge *big.Int) (bool, error) { - return _TokenBridge.Contract.IsCurrentConsensusValue(&_TokenBridge.CallOpts, _attest, _currentValidatorSet, _sigs, _maxAttestationAge) +// Solidity: function getTimeOfLastNewValue() view returns(uint256) +func (_TokenBridge *TokenBridgeSession) GetTimeOfLastNewValue() (*big.Int, error) { + return _TokenBridge.Contract.GetTimeOfLastNewValue(&_TokenBridge.CallOpts) } -// IsCurrentConsensusValue is a free data retrieval call binding the contract method 0x601319eb. +// GetTimeOfLastNewValue is a free data retrieval call binding the contract method 0xc0f95d52. // -// Solidity: function isCurrentConsensusValue((bytes32,(bytes,uint256,uint256,uint256,uint256),uint256) _attest, (address,uint256)[] _currentValidatorSet, (uint8,bytes32,bytes32)[] _sigs, uint256 _maxAttestationAge) view returns(bool) -func (_TokenBridge *TokenBridgeCallerSession) IsCurrentConsensusValue(_attest OracleAttestationData, _currentValidatorSet []Validator, _sigs []Signature, _maxAttestationAge *big.Int) (bool, error) { - return _TokenBridge.Contract.IsCurrentConsensusValue(&_TokenBridge.CallOpts, _attest, _currentValidatorSet, _sigs, _maxAttestationAge) +// Solidity: function getTimeOfLastNewValue() view returns(uint256) +func (_TokenBridge *TokenBridgeCallerSession) GetTimeOfLastNewValue() (*big.Int, error) { + return _TokenBridge.Contract.GetTimeOfLastNewValue(&_TokenBridge.CallOpts) } -// IsValidDataAfter is a free data retrieval call binding the contract method 0x6329f706. +// GetTimestampbyQueryIdandIndex is a free data retrieval call binding the contract method 0xce5e11bf. // -// Solidity: function isValidDataAfter((bytes32,(bytes,uint256,uint256,uint256,uint256),uint256) _attest, (address,uint256)[] _currentValidatorSet, (uint8,bytes32,bytes32)[] _sigs, uint256 _timestampAfter, uint256 _maxAge, uint256 _minimumPower, uint256 _maxAttestationAge) view returns(bool) -func (_TokenBridge *TokenBridgeCaller) IsValidDataAfter(opts *bind.CallOpts, _attest OracleAttestationData, _currentValidatorSet []Validator, _sigs []Signature, _timestampAfter *big.Int, _maxAge *big.Int, _minimumPower *big.Int, _maxAttestationAge *big.Int) (bool, error) { +// Solidity: function getTimestampbyQueryIdandIndex(bytes32 _queryId, uint256 _index) view returns(uint256) +func (_TokenBridge *TokenBridgeCaller) GetTimestampbyQueryIdandIndex(opts *bind.CallOpts, _queryId [32]byte, _index *big.Int) (*big.Int, error) { var out []interface{} - err := _TokenBridge.contract.Call(opts, &out, "isValidDataAfter", _attest, _currentValidatorSet, _sigs, _timestampAfter, _maxAge, _minimumPower, _maxAttestationAge) + err := _TokenBridge.contract.Call(opts, &out, "getTimestampbyQueryIdandIndex", _queryId, _index) if err != nil { - return *new(bool), err + return *new(*big.Int), err } - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) return out0, err } -// IsValidDataAfter is a free data retrieval call binding the contract method 0x6329f706. +// GetTimestampbyQueryIdandIndex is a free data retrieval call binding the contract method 0xce5e11bf. // -// Solidity: function isValidDataAfter((bytes32,(bytes,uint256,uint256,uint256,uint256),uint256) _attest, (address,uint256)[] _currentValidatorSet, (uint8,bytes32,bytes32)[] _sigs, uint256 _timestampAfter, uint256 _maxAge, uint256 _minimumPower, uint256 _maxAttestationAge) view returns(bool) -func (_TokenBridge *TokenBridgeSession) IsValidDataAfter(_attest OracleAttestationData, _currentValidatorSet []Validator, _sigs []Signature, _timestampAfter *big.Int, _maxAge *big.Int, _minimumPower *big.Int, _maxAttestationAge *big.Int) (bool, error) { - return _TokenBridge.Contract.IsValidDataAfter(&_TokenBridge.CallOpts, _attest, _currentValidatorSet, _sigs, _timestampAfter, _maxAge, _minimumPower, _maxAttestationAge) +// Solidity: function getTimestampbyQueryIdandIndex(bytes32 _queryId, uint256 _index) view returns(uint256) +func (_TokenBridge *TokenBridgeSession) GetTimestampbyQueryIdandIndex(_queryId [32]byte, _index *big.Int) (*big.Int, error) { + return _TokenBridge.Contract.GetTimestampbyQueryIdandIndex(&_TokenBridge.CallOpts, _queryId, _index) } -// IsValidDataAfter is a free data retrieval call binding the contract method 0x6329f706. +// GetTimestampbyQueryIdandIndex is a free data retrieval call binding the contract method 0xce5e11bf. // -// Solidity: function isValidDataAfter((bytes32,(bytes,uint256,uint256,uint256,uint256),uint256) _attest, (address,uint256)[] _currentValidatorSet, (uint8,bytes32,bytes32)[] _sigs, uint256 _timestampAfter, uint256 _maxAge, uint256 _minimumPower, uint256 _maxAttestationAge) view returns(bool) -func (_TokenBridge *TokenBridgeCallerSession) IsValidDataAfter(_attest OracleAttestationData, _currentValidatorSet []Validator, _sigs []Signature, _timestampAfter *big.Int, _maxAge *big.Int, _minimumPower *big.Int, _maxAttestationAge *big.Int) (bool, error) { - return _TokenBridge.Contract.IsValidDataAfter(&_TokenBridge.CallOpts, _attest, _currentValidatorSet, _sigs, _timestampAfter, _maxAge, _minimumPower, _maxAttestationAge) +// Solidity: function getTimestampbyQueryIdandIndex(bytes32 _queryId, uint256 _index) view returns(uint256) +func (_TokenBridge *TokenBridgeCallerSession) GetTimestampbyQueryIdandIndex(_queryId [32]byte, _index *big.Int) (*big.Int, error) { + return _TokenBridge.Contract.GetTimestampbyQueryIdandIndex(&_TokenBridge.CallOpts, _queryId, _index) } -// IsValidDataBefore is a free data retrieval call binding the contract method 0x3113975b. +// IsInDispute is a free data retrieval call binding the contract method 0x44e87f91. // -// Solidity: function isValidDataBefore((bytes32,(bytes,uint256,uint256,uint256,uint256),uint256) _attest, (address,uint256)[] _currentValidatorSet, (uint8,bytes32,bytes32)[] _sigs, uint256 _timestampBefore, uint256 _maxReportAge, uint256 _minimumPower, uint256 _maxAttestationAge) view returns(bool) -func (_TokenBridge *TokenBridgeCaller) IsValidDataBefore(opts *bind.CallOpts, _attest OracleAttestationData, _currentValidatorSet []Validator, _sigs []Signature, _timestampBefore *big.Int, _maxReportAge *big.Int, _minimumPower *big.Int, _maxAttestationAge *big.Int) (bool, error) { +// Solidity: function isInDispute(bytes32 _queryId, uint256 _timestamp) view returns(bool) +func (_TokenBridge *TokenBridgeCaller) IsInDispute(opts *bind.CallOpts, _queryId [32]byte, _timestamp *big.Int) (bool, error) { var out []interface{} - err := _TokenBridge.contract.Call(opts, &out, "isValidDataBefore", _attest, _currentValidatorSet, _sigs, _timestampBefore, _maxReportAge, _minimumPower, _maxAttestationAge) + err := _TokenBridge.contract.Call(opts, &out, "isInDispute", _queryId, _timestamp) if err != nil { return *new(bool), err @@ -644,18 +744,49 @@ func (_TokenBridge *TokenBridgeCaller) IsValidDataBefore(opts *bind.CallOpts, _a } -// IsValidDataBefore is a free data retrieval call binding the contract method 0x3113975b. +// IsInDispute is a free data retrieval call binding the contract method 0x44e87f91. +// +// Solidity: function isInDispute(bytes32 _queryId, uint256 _timestamp) view returns(bool) +func (_TokenBridge *TokenBridgeSession) IsInDispute(_queryId [32]byte, _timestamp *big.Int) (bool, error) { + return _TokenBridge.Contract.IsInDispute(&_TokenBridge.CallOpts, _queryId, _timestamp) +} + +// IsInDispute is a free data retrieval call binding the contract method 0x44e87f91. +// +// Solidity: function isInDispute(bytes32 _queryId, uint256 _timestamp) view returns(bool) +func (_TokenBridge *TokenBridgeCallerSession) IsInDispute(_queryId [32]byte, _timestamp *big.Int) (bool, error) { + return _TokenBridge.Contract.IsInDispute(&_TokenBridge.CallOpts, _queryId, _timestamp) +} + +// TellorFlex is a free data retrieval call binding the contract method 0xe513730b. +// +// Solidity: function tellorFlex() view returns(address) +func (_TokenBridge *TokenBridgeCaller) TellorFlex(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TokenBridge.contract.Call(opts, &out, "tellorFlex") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// TellorFlex is a free data retrieval call binding the contract method 0xe513730b. // -// Solidity: function isValidDataBefore((bytes32,(bytes,uint256,uint256,uint256,uint256),uint256) _attest, (address,uint256)[] _currentValidatorSet, (uint8,bytes32,bytes32)[] _sigs, uint256 _timestampBefore, uint256 _maxReportAge, uint256 _minimumPower, uint256 _maxAttestationAge) view returns(bool) -func (_TokenBridge *TokenBridgeSession) IsValidDataBefore(_attest OracleAttestationData, _currentValidatorSet []Validator, _sigs []Signature, _timestampBefore *big.Int, _maxReportAge *big.Int, _minimumPower *big.Int, _maxAttestationAge *big.Int) (bool, error) { - return _TokenBridge.Contract.IsValidDataBefore(&_TokenBridge.CallOpts, _attest, _currentValidatorSet, _sigs, _timestampBefore, _maxReportAge, _minimumPower, _maxAttestationAge) +// Solidity: function tellorFlex() view returns(address) +func (_TokenBridge *TokenBridgeSession) TellorFlex() (common.Address, error) { + return _TokenBridge.Contract.TellorFlex(&_TokenBridge.CallOpts) } -// IsValidDataBefore is a free data retrieval call binding the contract method 0x3113975b. +// TellorFlex is a free data retrieval call binding the contract method 0xe513730b. // -// Solidity: function isValidDataBefore((bytes32,(bytes,uint256,uint256,uint256,uint256),uint256) _attest, (address,uint256)[] _currentValidatorSet, (uint8,bytes32,bytes32)[] _sigs, uint256 _timestampBefore, uint256 _maxReportAge, uint256 _minimumPower, uint256 _maxAttestationAge) view returns(bool) -func (_TokenBridge *TokenBridgeCallerSession) IsValidDataBefore(_attest OracleAttestationData, _currentValidatorSet []Validator, _sigs []Signature, _timestampBefore *big.Int, _maxReportAge *big.Int, _minimumPower *big.Int, _maxAttestationAge *big.Int) (bool, error) { - return _TokenBridge.Contract.IsValidDataBefore(&_TokenBridge.CallOpts, _attest, _currentValidatorSet, _sigs, _timestampBefore, _maxReportAge, _minimumPower, _maxAttestationAge) +// Solidity: function tellorFlex() view returns(address) +func (_TokenBridge *TokenBridgeCallerSession) TellorFlex() (common.Address, error) { + return _TokenBridge.Contract.TellorFlex(&_TokenBridge.CallOpts) } // Token is a free data retrieval call binding the contract method 0xfc0c546a. @@ -689,6 +820,68 @@ func (_TokenBridge *TokenBridgeCallerSession) Token() (common.Address, error) { return _TokenBridge.Contract.Token(&_TokenBridge.CallOpts) } +// TokensToClaim is a free data retrieval call binding the contract method 0x1e868334. +// +// Solidity: function tokensToClaim(address ) view returns(uint256) +func (_TokenBridge *TokenBridgeCaller) TokensToClaim(opts *bind.CallOpts, arg0 common.Address) (*big.Int, error) { + var out []interface{} + err := _TokenBridge.contract.Call(opts, &out, "tokensToClaim", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// TokensToClaim is a free data retrieval call binding the contract method 0x1e868334. +// +// Solidity: function tokensToClaim(address ) view returns(uint256) +func (_TokenBridge *TokenBridgeSession) TokensToClaim(arg0 common.Address) (*big.Int, error) { + return _TokenBridge.Contract.TokensToClaim(&_TokenBridge.CallOpts, arg0) +} + +// TokensToClaim is a free data retrieval call binding the contract method 0x1e868334. +// +// Solidity: function tokensToClaim(address ) view returns(uint256) +func (_TokenBridge *TokenBridgeCallerSession) TokensToClaim(arg0 common.Address) (*big.Int, error) { + return _TokenBridge.Contract.TokensToClaim(&_TokenBridge.CallOpts, arg0) +} + +// Verify is a free data retrieval call binding the contract method 0xfc735e99. +// +// Solidity: function verify() pure returns(uint256) +func (_TokenBridge *TokenBridgeCaller) Verify(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _TokenBridge.contract.Call(opts, &out, "verify") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Verify is a free data retrieval call binding the contract method 0xfc735e99. +// +// Solidity: function verify() pure returns(uint256) +func (_TokenBridge *TokenBridgeSession) Verify() (*big.Int, error) { + return _TokenBridge.Contract.Verify(&_TokenBridge.CallOpts) +} + +// Verify is a free data retrieval call binding the contract method 0xfc735e99. +// +// Solidity: function verify() pure returns(uint256) +func (_TokenBridge *TokenBridgeCallerSession) Verify() (*big.Int, error) { + return _TokenBridge.Contract.Verify(&_TokenBridge.CallOpts) +} + // WithdrawalClaimed is a free data retrieval call binding the contract method 0x1d821854. // // Solidity: function withdrawalClaimed(uint256 ) view returns(bool) @@ -720,46 +913,88 @@ func (_TokenBridge *TokenBridgeCallerSession) WithdrawalClaimed(arg0 *big.Int) ( return _TokenBridge.Contract.WithdrawalClaimed(&_TokenBridge.CallOpts, arg0) } -// DepositToLayer is a paid mutator transaction binding the contract method 0x5f96ca6c. +// AddStakingRewards is a paid mutator transaction binding the contract method 0xd9c51cd4. +// +// Solidity: function addStakingRewards(uint256 _amount) returns() +func (_TokenBridge *TokenBridgeTransactor) AddStakingRewards(opts *bind.TransactOpts, _amount *big.Int) (*types.Transaction, error) { + return _TokenBridge.contract.Transact(opts, "addStakingRewards", _amount) +} + +// AddStakingRewards is a paid mutator transaction binding the contract method 0xd9c51cd4. +// +// Solidity: function addStakingRewards(uint256 _amount) returns() +func (_TokenBridge *TokenBridgeSession) AddStakingRewards(_amount *big.Int) (*types.Transaction, error) { + return _TokenBridge.Contract.AddStakingRewards(&_TokenBridge.TransactOpts, _amount) +} + +// AddStakingRewards is a paid mutator transaction binding the contract method 0xd9c51cd4. +// +// Solidity: function addStakingRewards(uint256 _amount) returns() +func (_TokenBridge *TokenBridgeTransactorSession) AddStakingRewards(_amount *big.Int) (*types.Transaction, error) { + return _TokenBridge.Contract.AddStakingRewards(&_TokenBridge.TransactOpts, _amount) +} + +// ClaimExtraWithdraw is a paid mutator transaction binding the contract method 0x285bbd48. +// +// Solidity: function claimExtraWithdraw(address _recipient) returns() +func (_TokenBridge *TokenBridgeTransactor) ClaimExtraWithdraw(opts *bind.TransactOpts, _recipient common.Address) (*types.Transaction, error) { + return _TokenBridge.contract.Transact(opts, "claimExtraWithdraw", _recipient) +} + +// ClaimExtraWithdraw is a paid mutator transaction binding the contract method 0x285bbd48. +// +// Solidity: function claimExtraWithdraw(address _recipient) returns() +func (_TokenBridge *TokenBridgeSession) ClaimExtraWithdraw(_recipient common.Address) (*types.Transaction, error) { + return _TokenBridge.Contract.ClaimExtraWithdraw(&_TokenBridge.TransactOpts, _recipient) +} + +// ClaimExtraWithdraw is a paid mutator transaction binding the contract method 0x285bbd48. +// +// Solidity: function claimExtraWithdraw(address _recipient) returns() +func (_TokenBridge *TokenBridgeTransactorSession) ClaimExtraWithdraw(_recipient common.Address) (*types.Transaction, error) { + return _TokenBridge.Contract.ClaimExtraWithdraw(&_TokenBridge.TransactOpts, _recipient) +} + +// DepositToLayer is a paid mutator transaction binding the contract method 0xf4913c7e. // -// Solidity: function depositToLayer(uint256 _amount, string _layerRecipient) returns() -func (_TokenBridge *TokenBridgeTransactor) DepositToLayer(opts *bind.TransactOpts, _amount *big.Int, _layerRecipient string) (*types.Transaction, error) { - return _TokenBridge.contract.Transact(opts, "depositToLayer", _amount, _layerRecipient) +// Solidity: function depositToLayer(uint256 _amount, uint256 _tip, string _layerRecipient) returns() +func (_TokenBridge *TokenBridgeTransactor) DepositToLayer(opts *bind.TransactOpts, _amount *big.Int, _tip *big.Int, _layerRecipient string) (*types.Transaction, error) { + return _TokenBridge.contract.Transact(opts, "depositToLayer", _amount, _tip, _layerRecipient) } -// DepositToLayer is a paid mutator transaction binding the contract method 0x5f96ca6c. +// DepositToLayer is a paid mutator transaction binding the contract method 0xf4913c7e. // -// Solidity: function depositToLayer(uint256 _amount, string _layerRecipient) returns() -func (_TokenBridge *TokenBridgeSession) DepositToLayer(_amount *big.Int, _layerRecipient string) (*types.Transaction, error) { - return _TokenBridge.Contract.DepositToLayer(&_TokenBridge.TransactOpts, _amount, _layerRecipient) +// Solidity: function depositToLayer(uint256 _amount, uint256 _tip, string _layerRecipient) returns() +func (_TokenBridge *TokenBridgeSession) DepositToLayer(_amount *big.Int, _tip *big.Int, _layerRecipient string) (*types.Transaction, error) { + return _TokenBridge.Contract.DepositToLayer(&_TokenBridge.TransactOpts, _amount, _tip, _layerRecipient) } -// DepositToLayer is a paid mutator transaction binding the contract method 0x5f96ca6c. +// DepositToLayer is a paid mutator transaction binding the contract method 0xf4913c7e. // -// Solidity: function depositToLayer(uint256 _amount, string _layerRecipient) returns() -func (_TokenBridge *TokenBridgeTransactorSession) DepositToLayer(_amount *big.Int, _layerRecipient string) (*types.Transaction, error) { - return _TokenBridge.Contract.DepositToLayer(&_TokenBridge.TransactOpts, _amount, _layerRecipient) +// Solidity: function depositToLayer(uint256 _amount, uint256 _tip, string _layerRecipient) returns() +func (_TokenBridge *TokenBridgeTransactorSession) DepositToLayer(_amount *big.Int, _tip *big.Int, _layerRecipient string) (*types.Transaction, error) { + return _TokenBridge.Contract.DepositToLayer(&_TokenBridge.TransactOpts, _amount, _tip, _layerRecipient) } // WithdrawFromLayer is a paid mutator transaction binding the contract method 0xe5d8b9dc. // -// Solidity: function withdrawFromLayer((bytes32,(bytes,uint256,uint256,uint256,uint256),uint256) _attest, (address,uint256)[] _valset, (uint8,bytes32,bytes32)[] _sigs, uint256 _depositId) returns() -func (_TokenBridge *TokenBridgeTransactor) WithdrawFromLayer(opts *bind.TransactOpts, _attest OracleAttestationData, _valset []Validator, _sigs []Signature, _depositId *big.Int) (*types.Transaction, error) { - return _TokenBridge.contract.Transact(opts, "withdrawFromLayer", _attest, _valset, _sigs, _depositId) +// Solidity: function withdrawFromLayer((bytes32,(bytes,uint256,uint256,uint256,uint256),uint256) _attestData, (address,uint256)[] _valset, (uint8,bytes32,bytes32)[] _sigs, uint256 _depositId) returns() +func (_TokenBridge *TokenBridgeTransactor) WithdrawFromLayer(opts *bind.TransactOpts, _attestData OracleAttestationData, _valset []Validator, _sigs []Signature, _depositId *big.Int) (*types.Transaction, error) { + return _TokenBridge.contract.Transact(opts, "withdrawFromLayer", _attestData, _valset, _sigs, _depositId) } // WithdrawFromLayer is a paid mutator transaction binding the contract method 0xe5d8b9dc. // -// Solidity: function withdrawFromLayer((bytes32,(bytes,uint256,uint256,uint256,uint256),uint256) _attest, (address,uint256)[] _valset, (uint8,bytes32,bytes32)[] _sigs, uint256 _depositId) returns() -func (_TokenBridge *TokenBridgeSession) WithdrawFromLayer(_attest OracleAttestationData, _valset []Validator, _sigs []Signature, _depositId *big.Int) (*types.Transaction, error) { - return _TokenBridge.Contract.WithdrawFromLayer(&_TokenBridge.TransactOpts, _attest, _valset, _sigs, _depositId) +// Solidity: function withdrawFromLayer((bytes32,(bytes,uint256,uint256,uint256,uint256),uint256) _attestData, (address,uint256)[] _valset, (uint8,bytes32,bytes32)[] _sigs, uint256 _depositId) returns() +func (_TokenBridge *TokenBridgeSession) WithdrawFromLayer(_attestData OracleAttestationData, _valset []Validator, _sigs []Signature, _depositId *big.Int) (*types.Transaction, error) { + return _TokenBridge.Contract.WithdrawFromLayer(&_TokenBridge.TransactOpts, _attestData, _valset, _sigs, _depositId) } // WithdrawFromLayer is a paid mutator transaction binding the contract method 0xe5d8b9dc. // -// Solidity: function withdrawFromLayer((bytes32,(bytes,uint256,uint256,uint256,uint256),uint256) _attest, (address,uint256)[] _valset, (uint8,bytes32,bytes32)[] _sigs, uint256 _depositId) returns() -func (_TokenBridge *TokenBridgeTransactorSession) WithdrawFromLayer(_attest OracleAttestationData, _valset []Validator, _sigs []Signature, _depositId *big.Int) (*types.Transaction, error) { - return _TokenBridge.Contract.WithdrawFromLayer(&_TokenBridge.TransactOpts, _attest, _valset, _sigs, _depositId) +// Solidity: function withdrawFromLayer((bytes32,(bytes,uint256,uint256,uint256,uint256),uint256) _attestData, (address,uint256)[] _valset, (uint8,bytes32,bytes32)[] _sigs, uint256 _depositId) returns() +func (_TokenBridge *TokenBridgeTransactorSession) WithdrawFromLayer(_attestData OracleAttestationData, _valset []Validator, _sigs []Signature, _depositId *big.Int) (*types.Transaction, error) { + return _TokenBridge.Contract.WithdrawFromLayer(&_TokenBridge.TransactOpts, _attestData, _valset, _sigs, _depositId) } // TokenBridgeDepositIterator is returned from FilterDeposit and is used to iterate over the raw logs and unpacked data for Deposit events raised by the TokenBridge contract. @@ -835,12 +1070,13 @@ type TokenBridgeDeposit struct { Sender common.Address Recipient string Amount *big.Int + Tip *big.Int Raw types.Log // Blockchain specific contextual infos } -// FilterDeposit is a free log retrieval operation binding the contract event 0xaeefb35576420985ebd638138c7f004039a2154c74d548ae18603b54a5f1bdc5. +// FilterDeposit is a free log retrieval operation binding the contract event 0xe9a436e6735e7a54b0d2505d14247a614f3af68dad813a7a46834b876b13d7c1. // -// Solidity: event Deposit(uint256 depositId, address sender, string recipient, uint256 amount) +// Solidity: event Deposit(uint256 _depositId, address _sender, string _recipient, uint256 _amount, uint256 _tip) func (_TokenBridge *TokenBridgeFilterer) FilterDeposit(opts *bind.FilterOpts) (*TokenBridgeDepositIterator, error) { logs, sub, err := _TokenBridge.contract.FilterLogs(opts, "Deposit") @@ -850,9 +1086,9 @@ func (_TokenBridge *TokenBridgeFilterer) FilterDeposit(opts *bind.FilterOpts) (* return &TokenBridgeDepositIterator{contract: _TokenBridge.contract, event: "Deposit", logs: logs, sub: sub}, nil } -// WatchDeposit is a free log subscription operation binding the contract event 0xaeefb35576420985ebd638138c7f004039a2154c74d548ae18603b54a5f1bdc5. +// WatchDeposit is a free log subscription operation binding the contract event 0xe9a436e6735e7a54b0d2505d14247a614f3af68dad813a7a46834b876b13d7c1. // -// Solidity: event Deposit(uint256 depositId, address sender, string recipient, uint256 amount) +// Solidity: event Deposit(uint256 _depositId, address _sender, string _recipient, uint256 _amount, uint256 _tip) func (_TokenBridge *TokenBridgeFilterer) WatchDeposit(opts *bind.WatchOpts, sink chan<- *TokenBridgeDeposit) (event.Subscription, error) { logs, sub, err := _TokenBridge.contract.WatchLogs(opts, "Deposit") @@ -887,9 +1123,9 @@ func (_TokenBridge *TokenBridgeFilterer) WatchDeposit(opts *bind.WatchOpts, sink }), nil } -// ParseDeposit is a log parse operation binding the contract event 0xaeefb35576420985ebd638138c7f004039a2154c74d548ae18603b54a5f1bdc5. +// ParseDeposit is a log parse operation binding the contract event 0xe9a436e6735e7a54b0d2505d14247a614f3af68dad813a7a46834b876b13d7c1. // -// Solidity: event Deposit(uint256 depositId, address sender, string recipient, uint256 amount) +// Solidity: event Deposit(uint256 _depositId, address _sender, string _recipient, uint256 _amount, uint256 _tip) func (_TokenBridge *TokenBridgeFilterer) ParseDeposit(log types.Log) (*TokenBridgeDeposit, error) { event := new(TokenBridgeDeposit) if err := _TokenBridge.contract.UnpackLog(event, "Deposit", log); err != nil { @@ -977,7 +1213,7 @@ type TokenBridgeWithdrawal struct { // FilterWithdrawal is a free log retrieval operation binding the contract event 0x1c25a916bf61b55f3abb9060e620d13d6937f8c2ab2b7a16be824ffde44acb2f. // -// Solidity: event Withdrawal(uint256 depositId, string sender, address recipient, uint256 amount) +// Solidity: event Withdrawal(uint256 _depositId, string _sender, address _recipient, uint256 _amount) func (_TokenBridge *TokenBridgeFilterer) FilterWithdrawal(opts *bind.FilterOpts) (*TokenBridgeWithdrawalIterator, error) { logs, sub, err := _TokenBridge.contract.FilterLogs(opts, "Withdrawal") @@ -989,7 +1225,7 @@ func (_TokenBridge *TokenBridgeFilterer) FilterWithdrawal(opts *bind.FilterOpts) // WatchWithdrawal is a free log subscription operation binding the contract event 0x1c25a916bf61b55f3abb9060e620d13d6937f8c2ab2b7a16be824ffde44acb2f. // -// Solidity: event Withdrawal(uint256 depositId, string sender, address recipient, uint256 amount) +// Solidity: event Withdrawal(uint256 _depositId, string _sender, address _recipient, uint256 _amount) func (_TokenBridge *TokenBridgeFilterer) WatchWithdrawal(opts *bind.WatchOpts, sink chan<- *TokenBridgeWithdrawal) (event.Subscription, error) { logs, sub, err := _TokenBridge.contract.WatchLogs(opts, "Withdrawal") @@ -1026,7 +1262,7 @@ func (_TokenBridge *TokenBridgeFilterer) WatchWithdrawal(opts *bind.WatchOpts, s // ParseWithdrawal is a log parse operation binding the contract event 0x1c25a916bf61b55f3abb9060e620d13d6937f8c2ab2b7a16be824ffde44acb2f. // -// Solidity: event Withdrawal(uint256 depositId, string sender, address recipient, uint256 amount) +// Solidity: event Withdrawal(uint256 _depositId, string _sender, address _recipient, uint256 _amount) func (_TokenBridge *TokenBridgeFilterer) ParseWithdrawal(log types.Log) (*TokenBridgeWithdrawal, error) { event := new(TokenBridgeWithdrawal) if err := _TokenBridge.contract.UnpackLog(event, "Withdrawal", log); err != nil { diff --git a/daemons/token_bridge_feed/client/client.go b/daemons/token_bridge_feed/client/client.go index 277e8cce5..61526e4f0 100644 --- a/daemons/token_bridge_feed/client/client.go +++ b/daemons/token_bridge_feed/client/client.go @@ -100,6 +100,7 @@ type DepositReceipt struct { Sender common.Address Recipient string Amount *big.Int + Tip *big.Int BlockHeight *big.Int } @@ -144,7 +145,7 @@ func (c *Client) InitializeDeposits() error { c.ethClient = eclient - contractAddress := common.HexToAddress("0x1AaF421491171930e71fb032B765DF252CE3F97e") + contractAddress := common.HexToAddress("0x717F9269032C25D91CcD92bADbdfcb32c30E9492") bridgeContract, err := tokenbridge.NewTokenBridge(contractAddress, c.ethClient) if err != nil { @@ -235,6 +236,7 @@ func (c *Client) QueryDepositDetails(depositId *big.Int) (DepositReceipt, error) Sender: depositDetails.Sender, Recipient: depositDetails.Recipient, Amount: depositDetails.Amount, + Tip: depositDetails.Tip, BlockHeight: depositDetails.BlockHeight, } @@ -332,10 +334,11 @@ func (c *Client) EncodeReportValue(depositReceipt DepositReceipt) ([]byte, error {Type: AddressType}, {Type: StringType}, {Type: Uint256Type}, + {Type: Uint256Type}, } // encode report value arguments - reportValueArgsEncoded, err := reportValueArgs.Pack(depositReceipt.Sender, depositReceipt.Recipient, depositReceipt.Amount) + reportValueArgsEncoded, err := reportValueArgs.Pack(depositReceipt.Sender, depositReceipt.Recipient, depositReceipt.Amount, depositReceipt.Tip) if err != nil { return nil, err } diff --git a/evm/README.md b/evm/README.md index 6eef6bdf0..b463d3372 100644 --- a/evm/README.md +++ b/evm/README.md @@ -21,7 +21,7 @@ Then add your node url to `.env`: NODE_URL="your-node-url" ``` -Then install dependencies from this `evm` dir: +Install dependencies from this `evm` dir: ```bash npm i ``` @@ -44,6 +44,12 @@ Or on Ubuntu, sudo apt-get install jq ``` +Comment out the following lines in `x/reporter/ante/ante.go`, lines 34-35 at the time of writing. This will allow you to run a second validator which changes the validator power by more than 5%. +```go +// case *stakingtypes.MsgCreateValidator: +// msgAmount = msg.Value.Amount +``` + In `terminal-1`, go to the layer root directory and run: ```bash chmod 755 ./start_scripts/start_two_chains.sh @@ -56,6 +62,14 @@ In `terminal-2`, run: ./start_scripts/start_bill.sh ``` +In `terminal-3`, create two reporters: +```bash +./layerd tx reporter create-reporter "100000000000000000" "1000000" --from alice --keyring-backend test --chain-id layertest-1 --home ~/.layer/alice --keyring-dir ~/.layer/alice --fees 1000loya --yes +``` +and for bill: +```bash +./layerd tx reporter create-reporter "100000000000000000" "1000000" --from bill --keyring-backend test --chain-id layertest-1 --home ~/.layer/bill --keyring-dir ~/.layer/bill --fees 1000loya --yes +``` ### TokenBridge-FunctionTests with Live chain @@ -69,7 +83,7 @@ But you can request to withdraw tokens from layer by running this from the layer ```bash charlies_address=$(./layerd keys show charlie --home ~/.layer/alice -a) -./layerd tx bridge withdraw-tokens $charlies_address 88dF592F8eb5D7Bd38bFeF7dEb0fBc02cf3778a0 100loya --from $charlies_address --chain-id layer --home ~/.layer/alice --keyring-backend test --keyring-dir ~/.layer/alice +./layerd tx bridge withdraw-tokens $charlies_address 88dF592F8eb5D7Bd38bFeF7dEb0fBc02cf3778a0 100loya --from $charlies_address --chain-id layertest-1 --home ~/.layer/alice --keyring-backend test --keyring-dir ~/.layer/alice --fees 500loya --yes ``` ### Live chain bridge-TestsAuto @@ -81,8 +95,8 @@ npx hardhat test fullTest/Bridge-TestsAuto.js All tests should pass except for the "optimistic value" test, but you should see a timestamp printed out. Use this timestamp in place of {timestamp} in the command below to request new attestations: ```bash charlies_address=$(./layerd keys show charlie --home ~/.layer/alice -a) -./layerd tx bridge request-attestations $charlies_address 83a7f3d48786ac2667503a61e8c415438ed2922eb86a2906e4ee66d9a2ce4992 {timestamp} --from $charlies_address --chain-id layer --home ~/.layer/alice --keyring-backend test --keyring-dir ~/.layer/alice +./layerd tx bridge request-attestations $charlies_address 83a7f3d48786ac2667503a61e8c415438ed2922eb86a2906e4ee66d9a2ce4992 {timestamp} --from charlie --chain-id layertest-1 --keyring-backend test --keyring-dir ~/.layer/alice --fees 1000loya --yes ``` -Update the `PAST_REPORT_TS` variable in the test file, and re-run the tests. +Update the `PAST_REPORT_TS` variable in the test file with the same timestamp you used above, and re-run the tests. diff --git a/evm/contracts/interfaces/IBlobstreamO.sol b/evm/contracts/interfaces/IBlobstreamO.sol new file mode 100644 index 000000000..109ec18fe --- /dev/null +++ b/evm/contracts/interfaces/IBlobstreamO.sol @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +struct OracleAttestationData { + bytes32 queryId; + ReportData report; + uint256 attestationTimestamp;//timestamp of validatorSignatures on report +} + +struct ReportData { + bytes value; + uint256 timestamp;//timestamp of reporter signature aggregation + uint256 aggregatePower; + uint256 previousTimestamp; + uint256 nextTimestamp; +} + +struct Signature { + uint8 v; + bytes32 r; + bytes32 s; +} + +struct Validator { + address addr; + uint256 power; +} + +interface IBlobstreamO { + function guardian() external view returns (address); + function powerThreshold() external view returns (uint256); + function unbondingPeriod() external view returns (uint256); + function validatorTimestamp() external view returns (uint256); + function verifyOracleData( + OracleAttestationData calldata _attestData, + Validator[] calldata _currentValidatorSet, + Signature[] calldata _sigs + ) external view; +} \ No newline at end of file diff --git a/evm/contracts/interfaces/ITellorMaster.sol b/evm/contracts/interfaces/ITellorMaster.sol index d082eb114..88c37d418 100644 --- a/evm/contracts/interfaces/ITellorMaster.sol +++ b/evm/contracts/interfaces/ITellorMaster.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.22; +pragma solidity ^0.8.0; interface ITellorMaster { function allowance(address owner, address spender) external view returns (uint256); diff --git a/evm/contracts/testing/SimpleLayerUser.sol b/evm/contracts/testing/SimpleLayerUser.sol index 15de1613f..6c6515f60 100644 --- a/evm/contracts/testing/SimpleLayerUser.sol +++ b/evm/contracts/testing/SimpleLayerUser.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.22; -import "../bridge/BlobstreamO.sol"; +import "../interfaces/IBlobstreamO.sol"; contract SimpleLayerUser { - BlobstreamO public blobstreamO; + IBlobstreamO public blobstreamO; PriceData[] public priceData; bytes32 public queryId; @@ -18,7 +18,7 @@ contract SimpleLayerUser { } constructor(address _blobstreamO, bytes32 _queryId) { - blobstreamO = BlobstreamO(_blobstreamO); + blobstreamO = IBlobstreamO(_blobstreamO); queryId = _queryId; } diff --git a/evm/contracts/testing/TestTokenBridge.sol b/evm/contracts/testing/TestTokenBridge.sol index d3e17336c..0753e76c8 100644 --- a/evm/contracts/testing/TestTokenBridge.sol +++ b/evm/contracts/testing/TestTokenBridge.sol @@ -11,7 +11,7 @@ contract TestTokenBridge is TokenBridge{ } /// @notice refreshes the deposit limit every 12 hours so no one can spam layer with new tokens - function refreshDepositLimit() external returns (uint256) { - return _refreshDepositLimit(); + function refreshDepositLimit(uint256 _amount) external returns (uint256) { + return _refreshDepositLimit(_amount); } } diff --git a/evm/contracts/token-bridge/TokenBridge.sol b/evm/contracts/token-bridge/TokenBridge.sol index 702551060..898071bc7 100644 --- a/evm/contracts/token-bridge/TokenBridge.sol +++ b/evm/contracts/token-bridge/TokenBridge.sol @@ -1,9 +1,10 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.22; +pragma solidity 0.8.22; -import "../bridge/BlobstreamO.sol"; +import "../interfaces/IBlobstreamO.sol"; import { LayerTransition } from "./LayerTransition.sol"; +/// @author Tellor Inc. /// @title TokenBridge /// @dev This is the tellor token bridge to move tokens from /// Ethereum to layer. No one needs to do this. The only reason you @@ -12,14 +13,21 @@ import { LayerTransition } from "./LayerTransition.sol"; /// bridging back. There is a long delay in bridging back (enforced by layer) of 12 hours contract TokenBridge is LayerTransition{ /*Storage*/ - BlobstreamO public bridge; - uint256 public depositId;//counterOfHowManydeposits have been made - uint256 public depositLimitUpdateTime;//last time the limit was updated - uint256 public depositLimitRecord;//amount you can bridge per limit period - uint256 public constant DEPOSIT_LIMIT_UPDATE_INTERVAL = 12 hours; - uint256 public immutable DEPOSIT_LIMIT_DENOMINATOR = 100e18 / 20e18; // 100/depositLimitPercentage - - mapping(uint256 => bool) public withdrawalClaimed; // withdrawal id => claimed status + IBlobstreamO public bridge; + uint256 public depositId; // counter of how many deposits have been made + uint256 public depositLimitUpdateTime; // last time the deposit limit was updated + uint256 public depositLimitRecord; // amount you can deposit per limit period + BridgeState public bridgeState; // state of the bridge + uint256 public bridgeStateUpdateTime; // last time the bridge state was updated + uint256 public withdrawLimitUpdateTime; // last time the withdraw limit was updated + uint256 public withdrawLimitRecord; // amount you can withdraw per limit period + uint256 public constant DEPOSIT_LIMIT_DENOMINATOR = 100e18 / 20e18; // 100/depositLimitPercentage + uint256 public constant PAUSE_PERIOD = 21 days; // time period guardian can pause bridge, only once + uint256 public constant PAUSE_TRIBUTE_AMOUNT = 10000 ether; // amount of tokens burned to pause bridge + uint256 public constant TWELVE_HOUR_UPDATE_INTERVAL = 12 hours; // deposit and withdraw limits update interval + uint256 public constant WITHDRAW_LIMIT_DENOMINATOR = 100e18 / 5e18; // 100/withdrawLimitPercentage + + mapping(uint256 => bool) public withdrawClaimed; // withdraw id => claimed status mapping(address => uint256) public tokensToClaim; // recipient => extra amount to claim mapping(uint256 => DepositDetails) public deposits; // deposit id => deposit details @@ -27,12 +35,31 @@ contract TokenBridge is LayerTransition{ address sender; string recipient; uint256 amount; + uint256 tip; uint256 blockHeight; } + enum BridgeState { + NORMAL, + PAUSED, + UNPAUSED + } + /*Events*/ - event Deposit(uint256 _depositId, address _sender, string _recipient, uint256 _amount); - event Withdrawal(uint256 _depositId, string _sender, address _recipient, uint256 _amount); + event BridgeStateUpdated(BridgeState _newState); + event ExtraWithdrawClaimed(address _recipient, uint256 _amount); + event Deposit(uint256 _depositId, address _sender, string _recipient, uint256 _amount, uint256 _tip); + event Withdraw(uint256 _depositId, string _sender, address _recipient, uint256 _amount); + + // Functions + /** + * @dev Initializes system parameters + * @param _token address of token used for staking and rewards + * @param _reportingLock base amount of time (seconds) before reporter is able to report again + * @param _stakeAmountDollarTarget fixed USD amount that stakeAmount targets on updateStakeAmount + * @param _stakingTokenPrice current price of staking token in USD (18 decimals) + * @param _stakingTokenPriceQueryId queryId where staking token price is reported + */ /*Functions*/ /// @notice constructor @@ -40,39 +67,61 @@ contract TokenBridge is LayerTransition{ /// @param _blobstream address of BlobstreamO data bridge /// @param _tellorFlex address of oracle(tellorFlex) on chain constructor(address _token, address _blobstream, address _tellorFlex) LayerTransition(_tellorFlex, _token){ - bridge = BlobstreamO(_blobstream); + bridge = IBlobstreamO(_blobstream); } - /// @notice claim extra withdrawals that were not fully withdrawn + /// @notice claim extra withdraws that were not fully withdrawn /// @param _recipient address of the recipient function claimExtraWithdraw(address _recipient) external { + require(bridgeState != BridgeState.PAUSED, "TokenBridge: bridge is paused"); uint256 _amountConverted = tokensToClaim[_recipient]; require(_amountConverted > 0, "amount must be > 0"); - uint256 _depositLimit = _refreshDepositLimit(); - require(_depositLimit > 0, "TokenBridge: depositLimit must be > 0"); - if(_depositLimit < _amountConverted){ - tokensToClaim[_recipient] = tokensToClaim[_recipient] - _depositLimit; - _amountConverted = _depositLimit; - require(token.transfer(_recipient, _amountConverted), "TokenBridge: transfer failed"); + uint256 _withdrawLimit = _refreshWithdrawLimit(_amountConverted); + require(_withdrawLimit > 0, "TokenBridge: withdraw limit must be > 0"); + if(_withdrawLimit < _amountConverted){ + tokensToClaim[_recipient] = tokensToClaim[_recipient] - _withdrawLimit; + _amountConverted = _withdrawLimit; } else{ tokensToClaim[_recipient] = 0; - require(token.transfer(_recipient, _amountConverted), "TokenBridge: transfer failed"); } - depositLimitRecord -= _amountConverted; + withdrawLimitRecord -= _amountConverted; + require(token.transfer(_recipient, _amountConverted), "TokenBridge: transfer failed"); + emit ExtraWithdrawClaimed(_recipient, _amountConverted); } /// @notice deposits tokens from Ethereum to layer - /// @param _amount amount of tokens to bridge over + /// @param _amount total amount of tokens to bridge over + /// @param _tip amount of tokens to tip the claimDeposit caller on layer /// @param _layerRecipient your cosmos address on layer (don't get it wrong!!) - function depositToLayer(uint256 _amount, string memory _layerRecipient) external { - require(_amount > 0, "TokenBridge: amount must be greater than 0"); - require(_amount <= _refreshDepositLimit(), "TokenBridge: amount exceeds deposit limit for time period"); + function depositToLayer(uint256 _amount, uint256 _tip, string memory _layerRecipient) external { + require(_amount > 0.1 ether, "TokenBridge: amount must be greater than 0.1 tokens"); + require(_amount <= _refreshDepositLimit(_amount), "TokenBridge: amount exceeds deposit limit for time period"); + require(_tip <= _amount, "TokenBridge: tip must be less than or equal to amount"); + if (_tip > 0) { + require(_tip >= 1e12, "TokenBridge: tip must be greater than or equal to 1 loya"); + } require(token.transferFrom(msg.sender, address(this), _amount), "TokenBridge: transferFrom failed"); depositId++; depositLimitRecord -= _amount; - deposits[depositId] = DepositDetails(msg.sender, _layerRecipient, _amount, block.number); - emit Deposit(depositId, msg.sender, _layerRecipient, _amount); + deposits[depositId] = DepositDetails(msg.sender, _layerRecipient, _amount, _tip, block.number); + emit Deposit(depositId, msg.sender, _layerRecipient, _amount, _tip); + } + + function pauseBridge() external { + require(msg.sender == bridge.guardian(), "TokenBridge: only guardian can pause bridge"); + require(bridgeState == BridgeState.NORMAL, "TokenBridge: can only pause once"); + require(token.transferFrom(msg.sender, address(0xdEaD), PAUSE_TRIBUTE_AMOUNT), "TokenBridge: transfer failed"); + bridgeState = BridgeState.PAUSED; + bridgeStateUpdateTime = block.timestamp; + emit BridgeStateUpdated(BridgeState.PAUSED); + } + + function unpauseBridge() external { + require(bridgeState == BridgeState.PAUSED, "TokenBridge: bridge is not paused"); + require(block.timestamp - bridgeStateUpdateTime > PAUSE_PERIOD, "TokenBridge: must wait before unpausing"); + bridgeState = BridgeState.UNPAUSED; + emit BridgeStateUpdated(BridgeState.UNPAUSED); } /// @notice This withdraws tokens from layer to mainnet Ethereum @@ -86,32 +135,31 @@ contract TokenBridge is LayerTransition{ Signature[] calldata _sigs, uint256 _depositId ) external { + require(bridgeState != BridgeState.PAUSED, "TokenBridge: bridge is paused"); require(_attestData.queryId == keccak256(abi.encode("TRBBridge", abi.encode(false, _depositId))), "TokenBridge: invalid queryId"); - require(!withdrawalClaimed[_depositId], "TokenBridge: withdrawal already claimed"); + require(!withdrawClaimed[_depositId], "TokenBridge: withdraw already claimed"); require(block.timestamp - (_attestData.report.timestamp / 1000) > 12 hours, "TokenBridge: premature attestation"); require(block.timestamp - (_attestData.attestationTimestamp / 1000) < 12 hours, "TokenBridge: attestation too old"); bridge.verifyOracleData(_attestData, _valset, _sigs); require(_attestData.report.aggregatePower >= bridge.powerThreshold(), "Report aggregate power must be greater than or equal to _minimumPower"); - withdrawalClaimed[_depositId] = true; - (address _recipient, string memory _layerSender,uint256 _amountLoya) = abi.decode(_attestData.report.value, (address, string, uint256)); + withdrawClaimed[_depositId] = true; + (address _recipient, string memory _layerSender,uint256 _amountLoya,) = abi.decode(_attestData.report.value, (address, string, uint256, uint256)); uint256 _amountConverted = _amountLoya * 1e12; - uint256 _depositLimit = _refreshDepositLimit(); - if(_depositLimit < _amountConverted){ - tokensToClaim[_recipient] = tokensToClaim[_recipient] + (_amountConverted - _depositLimit); - _amountConverted = _depositLimit; - require(token.transfer(_recipient, _amountConverted), "TokenBridge: transfer failed"); + uint256 _withdrawLimit = _refreshWithdrawLimit(_amountConverted); + if(_withdrawLimit < _amountConverted){ + tokensToClaim[_recipient] = tokensToClaim[_recipient] + (_amountConverted - _withdrawLimit); + _amountConverted = _withdrawLimit; } - else{ - require(token.transfer(_recipient, _amountConverted), "TokenBridge: transfer failed"); - } - depositLimitRecord -= _amountConverted; - emit Withdrawal(_depositId, _layerSender, _recipient, _amountConverted); + withdrawLimitRecord -= _amountConverted; + require(token.transfer(_recipient, _amountConverted), "TokenBridge: transfer failed"); + emit Withdraw(_depositId, _layerSender, _recipient, _amountConverted); } /* View Functions */ - /// @notice refreshes the deposit limit every 12 hours so no one can spam layer with new tokens + /// @notice returns the amount of tokens that can be deposited in the current 12 hour period + /// @return amount of tokens that can be deposited function depositLimit() external view returns (uint256) { - if (block.timestamp - depositLimitUpdateTime > DEPOSIT_LIMIT_UPDATE_INTERVAL) { + if (block.timestamp - depositLimitUpdateTime > TWELVE_HOUR_UPDATE_INTERVAL) { return token.balanceOf(address(this)) / DEPOSIT_LIMIT_DENOMINATOR; } else{ @@ -119,12 +167,24 @@ contract TokenBridge is LayerTransition{ } } + /// @notice returns the withdraw limit + /// @return amount of tokens that can be withdrawn + function withdrawLimit() external view returns (uint256) { + if (block.timestamp - withdrawLimitUpdateTime > TWELVE_HOUR_UPDATE_INTERVAL) { + return token.balanceOf(address(this)) / WITHDRAW_LIMIT_DENOMINATOR; + } + else{ + return withdrawLimitRecord; + } + } + /* Internal Functions */ /// @notice refreshes the deposit limit every 12 hours so no one can spam layer with new tokens - function _refreshDepositLimit() internal returns (uint256) { - if (block.timestamp - depositLimitUpdateTime > DEPOSIT_LIMIT_UPDATE_INTERVAL) { + /// @return max amount of tokens that can be deposited + function _refreshDepositLimit(uint256 _amount) internal returns (uint256) { + if (block.timestamp - depositLimitUpdateTime > TWELVE_HOUR_UPDATE_INTERVAL) { uint256 _tokenBalance = token.balanceOf(address(this)); - if (_tokenBalance < 100 ether) { + if (_tokenBalance < _amount) { token.mintToOracle(); _tokenBalance = token.balanceOf(address(this)); } @@ -133,4 +193,20 @@ contract TokenBridge is LayerTransition{ } return depositLimitRecord; } + + /// @notice refreshes the withdraw limit every 12 hours so no one can spam layer with new tokens + /// @param _amount of tokens to withdraw + /// @return max amount of tokens that can be withdrawn + function _refreshWithdrawLimit(uint256 _amount) internal returns (uint256) { + if (block.timestamp - withdrawLimitUpdateTime > TWELVE_HOUR_UPDATE_INTERVAL) { + uint256 _tokenBalance = token.balanceOf(address(this)); + if (_tokenBalance < _amount) { + token.mintToOracle(); + _tokenBalance = token.balanceOf(address(this)); + } + withdrawLimitRecord = _tokenBalance / WITHDRAW_LIMIT_DENOMINATOR; + withdrawLimitUpdateTime = block.timestamp; + } + return withdrawLimitRecord; + } } diff --git a/evm/fullTest/Bridge-TestsAuto.js b/evm/fullTest/Bridge-TestsAuto.js index d18739b7f..18f0b4060 100644 --- a/evm/fullTest/Bridge-TestsAuto.js +++ b/evm/fullTest/Bridge-TestsAuto.js @@ -34,26 +34,26 @@ describe("BlobstreamO - Auto Function and e2e Tests", function () { it("query layer api, deploy and verify with real params", async function () { vts0 = await h.getValsetTimestampByIndex(0) vp0 = await h.getValsetCheckpointParams(vts0) - console.log("deploying bridge...") + // console.log("deploying bridge...") bridge = await ethers.deployContract("BlobstreamO", [guardian.address]); await bridge.init(vp0.powerThreshold, vp0.timestamp, UNBONDING_PERIOD, vp0.checkpoint) vts1 = await h.getValsetTimestampByIndex(1) vp1 = await h.getValsetCheckpointParams(vts1) valSet0 = await h.getValset(vp0.timestamp) valSet1 = await h.getValset(vp1.timestamp) - console.log("valSet0: ", valSet0) - console.log("valSet1: ", valSet1) + // console.log("valSet0: ", valSet0) + // console.log("valSet1: ", valSet1) vsigs1 = await h.getValsetSigs(vp1.timestamp, valSet0, vp1.checkpoint) - console.log("valsetSigs1: ", vsigs1) - console.log("updating validator set...") + // console.log("valsetSigs1: ", vsigs1) + //console.log("updating validator set...") await bridge.updateValidatorSet(vp1.valsetHash, vp1.powerThreshold, vp1.timestamp, valSet0, vsigs1); ethUsdRep0 = await h.getCurrentAggregateReport(ETH_USD_QUERY_ID) - console.log("ethUsdRep0: ", ethUsdRep0) + // console.log("ethUsdRep0: ", ethUsdRep0) snapshots = await h.getSnapshotsByReport(ETH_USD_QUERY_ID, ethUsdRep0.report.timestamp) - console.log("snapshots: ", snapshots) + // console.log("snapshots: ", snapshots) lastSnapshot = snapshots[snapshots.length - 1] attestationData = await h.getAttestationDataBySnapshot(lastSnapshot) - console.log("attestationData: ", attestationData) + // console.log("attestationData: ", attestationData) oattests = await h.getAttestationsBySnapshot(lastSnapshot, valSet1) if (oattests.length == 0) { sleeptime = 2 @@ -61,8 +61,8 @@ describe("BlobstreamO - Auto Function and e2e Tests", function () { await h.sleep(2) oattests = await h.getAttestationsBySnapshot(lastSnapshot, valSet1) } - console.log("oattests: ", oattests) - console.log("verifying oracle data...") + // console.log("oattests: ", oattests) + // console.log("verifying oracle data...") await bridge.verifyOracleData( attestationData, valSet1, @@ -72,7 +72,7 @@ describe("BlobstreamO - Auto Function and e2e Tests", function () { it("optimistic value", async function () { // request new attestations on layer and update PAST_REPORT_TS - const PAST_REPORT_TS = 1721762307161 + const PAST_REPORT_TS = 1725039875058 vts0 = await h.getValsetTimestampByIndex(0) vp0 = await h.getValsetCheckpointParams(vts0) bridge = await ethers.deployContract("BlobstreamO", [guardian.address]); @@ -106,8 +106,10 @@ describe("BlobstreamO - Auto Function and e2e Tests", function () { )) console.log("oracle data verified") } catch (error) { - console.log("Please request new attestations for the past report timestamp: %s", pastReport.timestamp) - console.log("and update PAST_REPORT_TS variable.") + console.log("Please request new attestations for the eth/usd past report timestamp %s:", pastReport.timestamp) + console.log("\ncharlies_address=$(./layerd keys show charlie --home ~/.layer/alice -a)") + console.log("./layerd tx bridge request-attestations $charlies_address 83a7f3d48786ac2667503a61e8c415438ed2922eb86a2906e4ee66d9a2ce4992 %s --from charlie --chain-id layertest-1 --keyring-backend test --keyring-dir ~/.layer/alice --fees 1000loya --yes", pastReport.timestamp) + console.log("\nand update PAST_REPORT_TS variable.") assert(false) } }) diff --git a/evm/fullTest/TokenBridge-FunctionTests.js b/evm/fullTest/TokenBridge-FunctionTests.js index e8b3f3b85..a75ab2ebe 100644 --- a/evm/fullTest/TokenBridge-FunctionTests.js +++ b/evm/fullTest/TokenBridge-FunctionTests.js @@ -69,14 +69,14 @@ describe("TokenBridge - Function Tests", async function () { assert.equal(recipientBal.toString(), expectedBal) }) - it.only("depositToLayer", async function () { + it("depositToLayer", async function () { depositAmount = h.toWei("1") assert.equal(await token.balanceOf(await accounts[0].address), h.toWei("1000")) - await h.expectThrow(tbridge.depositToLayer(depositAmount, LAYER_RECIPIENT)) // not approved + await h.expectThrow(tbridge.depositToLayer(depositAmount, 0, LAYER_RECIPIENT)) // not approved await token.approve(await tbridge.address, h.toWei("1000")) - await h.expectThrow(tbridge.depositToLayer(0, LAYER_RECIPIENT)) // zero amount - await h.expectThrow(tbridge.depositToLayer(h.toWei("21"), LAYER_RECIPIENT)) // over limit - await tbridge.depositToLayer(depositAmount, LAYER_RECIPIENT) + await h.expectThrow(tbridge.depositToLayer(0, 0, LAYER_RECIPIENT)) // zero amount + await h.expectThrow(tbridge.depositToLayer(h.toWei("21"), 0, LAYER_RECIPIENT)) // over limit + await tbridge.depositToLayer(depositAmount, 0, LAYER_RECIPIENT) blocky1 = await h.getBlock() tbridgeBal = await token.balanceOf(await tbridge.address) @@ -96,7 +96,7 @@ describe("TokenBridge - Function Tests", async function () { assert.equal(await tbridge.depositId(), 1) - await h.advanceTime(43200) + await h.advanceTime(43201) expectedDepositLimit2 = (BigInt(100e18) + BigInt(depositAmount)) * BigInt(2) / BigInt(10) assert.equal(BigInt(await tbridge.depositLimit()), expectedDepositLimit2); }) @@ -106,10 +106,10 @@ describe("TokenBridge - Function Tests", async function () { assert.equal(BigInt(await tbridge.depositLimit()), expectedDepositLimit); await token.approve(await tbridge.address, h.toWei("1000")) depositAmount = h.toWei("2") - await tbridge.depositToLayer(depositAmount, LAYER_RECIPIENT) + await tbridge.depositToLayer(depositAmount, 0, LAYER_RECIPIENT) expectedDepositLimit = BigInt(100e18) * BigInt(2) / BigInt(10) - BigInt(depositAmount) assert.equal(BigInt(await tbridge.depositLimit()), expectedDepositLimit); - await h.advanceTime(43200) + await h.advanceTime(43201) expectedDepositLimit2 = (BigInt(100e18) + BigInt(depositAmount)) / BigInt(5) assert.equal(BigInt(await tbridge.depositLimit()), expectedDepositLimit2); }) diff --git a/evm/hardhat.config.js b/evm/hardhat.config.js index 68ca360a3..0c57d918b 100644 --- a/evm/hardhat.config.js +++ b/evm/hardhat.config.js @@ -2,7 +2,7 @@ //require("hardhat-gas-reporter"); require("dotenv").config(); require("@nomiclabs/hardhat-ethers"); -require("hardhat-gas-reporter"); +// require("hardhat-gas-reporter"); // require("@nomiclabs/hardhat-web3"); diff --git a/evm/test/TokenBridgeFunctionTestsHH.js b/evm/test/TokenBridgeFunctionTestsHH.js index 67ee0aa75..0d587347d 100644 --- a/evm/test/TokenBridgeFunctionTestsHH.js +++ b/evm/test/TokenBridgeFunctionTestsHH.js @@ -57,9 +57,10 @@ describe("TokenBridge - Function Tests", async function () { }) it("withdrawFromLayer", async function () { depositAmount = h.toWei("20") - await h.expectThrow(tbridge.depositToLayer(depositAmount, LAYER_RECIPIENT)) // not approved + tip = h.toWei("0") + await h.expectThrow(tbridge.depositToLayer(depositAmount, tip, LAYER_RECIPIENT)) // not approved await token.approve(await tbridge.address, h.toWei("100")) - await tbridge.depositToLayer(depositAmount, LAYER_RECIPIENT) + await tbridge.depositToLayer(depositAmount, tip, LAYER_RECIPIENT) await h.advanceTime(43200) value = h.getWithdrawValue(EVM_RECIPIENT,LAYER_RECIPIENT,20) blocky = await h.getBlock() @@ -102,16 +103,110 @@ describe("TokenBridge - Function Tests", async function () { recipientBal = await token.balanceOf(EVM_RECIPIENT) expectedBal = 20e12 // 20 loya assert.equal(recipientBal.toString(), expectedBal) + + // assemble another withdraw, freeze bridge, then unfreeze + await token.faucet(accounts[0].address) + await token.transfer(tbridge.address, h.toWei("1000")) + await h.advanceTime(43200) + blocky = await h.getBlock() + timestamp = (blocky.timestamp - 43200) * 1000 + attestTimestamp = blocky.timestamp * 1000 + WITHDRAW2_QUERY_DATA_ARGS = abiCoder.encode(["bool", "uint256"], [false, 2]) + WITHDRAW2_QUERY_DATA = abiCoder.encode(["string", "bytes"], ["TRBBridge", WITHDRAW2_QUERY_DATA_ARGS]) + WITHDRAW2_QUERY_ID = h.hash(WITHDRAW2_QUERY_DATA) + value = h.getWithdrawValue(EVM_RECIPIENT,LAYER_RECIPIENT,20) + dataDigest = await h.getDataDigest( + WITHDRAW2_QUERY_ID, + value, + timestamp, + aggregatePower, + previousTimestamp, + nextTimestamp, + valCheckpoint, + attestTimestamp + ) + sig1 = await h.layerSign(dataDigest, val1.privateKey) + sig2 = await h.layerSign(dataDigest, val2.privateKey) + sigStructArray = await h.getSigStructArray([sig1, sig2]) + oracleDataStruct = await h.getOracleDataStruct( + WITHDRAW2_QUERY_ID, + value, + timestamp, + aggregatePower, + previousTimestamp, + nextTimestamp, + attestTimestamp + ) + for (let i = 0; i < 10; i++) { + await token.faucet(guardian.address) + } + await token.connect(guardian).approve(tbridge.address, h.toWei("10000")) + await tbridge.connect(guardian).pauseBridge() + await h.expectThrow(tbridge.withdrawFromLayer( + oracleDataStruct, + currentValSetArray, + sigStructArray, + 2 + )) + balanceDead = await token.balanceOf("0x000000000000000000000000000000000000dEaD") + assert.equal(balanceDead.toString(), h.toWei("10000")) + + await h.advanceTime(86400 * 21) + // update the validator set + blocky = await h.getBlock() + valTimestamp = (blocky.timestamp - 2) * 1000 + newValHash = await h.calculateValHash(initialValAddrs, initialPowers) + valCheckpoint = h.calculateValCheckpoint(newValHash, threshold, valTimestamp) + await blobstream.connect(guardian).guardianResetValidatorSet(threshold, valTimestamp, valCheckpoint) + + // withdraw + timestamp = (blocky.timestamp - 43200) * 1000 + attestTimestamp = blocky.timestamp * 1000 + value = h.getWithdrawValue(EVM_RECIPIENT,LAYER_RECIPIENT,20) + dataDigest = await h.getDataDigest( + WITHDRAW2_QUERY_ID, + value, + timestamp, + aggregatePower, + previousTimestamp, + nextTimestamp, + valCheckpoint, + attestTimestamp + ) + sig1 = await h.layerSign(dataDigest, val1.privateKey) + sig2 = await h.layerSign(dataDigest, val2.privateKey) + sigStructArray = await h.getSigStructArray([sig1, sig2]) + oracleDataStruct = await h.getOracleDataStruct( + WITHDRAW2_QUERY_ID, + value, + timestamp, + aggregatePower, + previousTimestamp, + nextTimestamp, + attestTimestamp + ) + await tbridge.unpauseBridge() + await tbridge.withdrawFromLayer( + oracleDataStruct, + currentValSetArray, + sigStructArray, + 2 + ) + recipientBal = await token.balanceOf(EVM_RECIPIENT) + expectedBal = 40e12 // 40 loya + assert.equal(recipientBal.toString(), expectedBal) }) it("depositToLayer", async function () { depositAmount = h.toWei("1") + tip = h.toWei(".01") assert.equal(await token.balanceOf(await accounts[0].address), h.toWei("1000")) assert.equal(await token.balanceOf(await tbridge.address), INITIAL_LAYER_TOKEN_SUPPLY) - await h.expectThrow(tbridge.depositToLayer(depositAmount, LAYER_RECIPIENT)) // not approved + await h.expectThrow(tbridge.depositToLayer(depositAmount, tip, LAYER_RECIPIENT)) // not approved await token.approve(await tbridge.address, h.toWei("900")) - await h.expectThrow(tbridge.depositToLayer(0, LAYER_RECIPIENT)) // zero amount - await h.expectThrow(tbridge.depositToLayer(h.toWei("21"), LAYER_RECIPIENT)) // over limit - await tbridge.depositToLayer(depositAmount, LAYER_RECIPIENT) + await h.expectThrow(tbridge.depositToLayer(0, tip, LAYER_RECIPIENT)) // zero amount + await h.expectThrow(tbridge.depositToLayer(h.toWei("21"), tip, LAYER_RECIPIENT)) // over limit + await h.expectThrow(tbridge.depositToLayer(depositAmount, h.toWei("1.01"), LAYER_RECIPIENT)) // tip over amount + await tbridge.depositToLayer(depositAmount, tip, LAYER_RECIPIENT) blocky1 = await h.getBlock() tbridgeBal = await token.balanceOf(await tbridge.address) expBalBridge = BigInt(depositAmount) + BigInt(INITIAL_LAYER_TOKEN_SUPPLY) @@ -120,48 +215,48 @@ describe("TokenBridge - Function Tests", async function () { assert.equal(userBal.toString(), h.toWei("999")) expectedDepositLimit = BigInt(100e18) * BigInt(2) / BigInt(10) - BigInt(depositAmount) assert.equal(BigInt(await tbridge.depositLimitRecord()), expectedDepositLimit); - await tbridge.refreshDepositLimit() + await tbridge.refreshDepositLimit(1) assert.equal(BigInt(await tbridge.depositLimitRecord()), expectedDepositLimit); assert.equal(await tbridge.depositId(), 1) depositDetails = await tbridge.deposits(1) assert.equal(depositDetails.amount.toString(), depositAmount) + assert.equal(depositDetails.tip.toString(), tip) assert.equal(depositDetails.recipient, LAYER_RECIPIENT) assert.equal(depositDetails.sender, await accounts[0].address) assert.equal(depositDetails.blockHeight, blocky1.number) assert.equal(await tbridge.depositId(), 1) await h.advanceTime(43200) expectedDepositLimit2 = (BigInt(100e18) + BigInt(depositAmount)) * BigInt(2) / BigInt(10) - await tbridge.refreshDepositLimit() + await tbridge.refreshDepositLimit(1) assert.equal(BigInt(await tbridge.depositLimitRecord()), expectedDepositLimit2); }) it("depositLimit", async function () { expectedDepositLimit = BigInt(100e18) * BigInt(2) / BigInt(10) - await tbridge.refreshDepositLimit() + await tbridge.refreshDepositLimit(1) assert.equal(BigInt(await tbridge.depositLimitRecord()), expectedDepositLimit); await token.approve(await tbridge.address, h.toWei("900")) depositAmount = h.toWei("2") - await tbridge.depositToLayer(depositAmount, LAYER_RECIPIENT) + tip = h.toWei("0") + await tbridge.depositToLayer(depositAmount, tip, LAYER_RECIPIENT) expectedDepositLimit = BigInt(100e18) * BigInt(2) / BigInt(10) - BigInt(depositAmount) - await tbridge.refreshDepositLimit() + await tbridge.refreshDepositLimit(1) assert.equal(BigInt(await tbridge.depositLimitRecord()), expectedDepositLimit); await h.advanceTime(43200) expectedDepositLimit2 = (BigInt(100e18) + BigInt(depositAmount)) / BigInt(5) - await tbridge.refreshDepositLimit() + await tbridge.refreshDepositLimit(1) assert.equal(BigInt(await tbridge.depositLimitRecord()), expectedDepositLimit2); }) - it("claim extraWithdraw", async function () { - await tbridge.refreshDepositLimit() - expectedDepositLimit = BigInt(INITIAL_LAYER_TOKEN_SUPPLY) * BigInt(2) / BigInt(10) - depositAmount = expectedDepositLimit - await h.expectThrow(tbridge.depositToLayer(depositAmount, LAYER_RECIPIENT)) // not approved - await token.approve(await tbridge.address, h.toWei("100")) - await tbridge.depositToLayer(depositAmount, LAYER_RECIPIENT) - await h.advanceTime(43200) - await token.approve(await tbridge.address, h.toWei("100")) - await tbridge.depositToLayer(depositAmount, LAYER_RECIPIENT) + + it("withdrawLimit", async function () { + expectedWithdrawLimit = BigInt(100e18) / BigInt(20) + withdrawLimit = await tbridge.withdrawLimit() + assert(withdrawLimit == expectedWithdrawLimit, "withdrawLimit should be correct") + }) + it("claimExtraWithdraw", async function () { + const WITHDRAW_AMOUNT = h.toWei("10") let _addy = await accounts[2].address - value = h.getWithdrawValue(_addy,LAYER_RECIPIENT,40000000) + value = h.getWithdrawValue(_addy,LAYER_RECIPIENT,BigInt(WITHDRAW_AMOUNT) / BigInt(1e12)) blocky = await h.getBlock() timestamp = (blocky.timestamp - 2) * 1000 aggregatePower = 3 @@ -194,8 +289,9 @@ describe("TokenBridge - Function Tests", async function () { attestTimestamp ) await h.advanceTime(43200) - await tbridge.refreshDepositLimit() - let _limit = await tbridge.depositLimit.call() + expectedWithdrawLimit = BigInt(INITIAL_LAYER_TOKEN_SUPPLY) / BigInt(20) + let _limit0 = await tbridge.withdrawLimit.call() + assert(_limit0 == expectedWithdrawLimit, "withdrawLimit should be correct") assert(await token.balanceOf(_addy) == 0) await tbridge.withdrawFromLayer( oracleDataStruct, @@ -203,24 +299,73 @@ describe("TokenBridge - Function Tests", async function () { sigStructArray, 1, ) - recipientBal = await token.balanceOf(_addy) - assert(recipientBal - _limit == 0, "token balance should be correct") + recipientBal0 = await token.balanceOf(_addy) + assert(recipientBal0 - _limit0 == 0, "token balance should be correct") tokensToClaim = await tbridge.tokensToClaim(accounts[2].address) - assert(tokensToClaim == BigInt(40e18) - BigInt(recipientBal), "tokensToClaim should be correct") + assert(tokensToClaim == BigInt(WITHDRAW_AMOUNT) - BigInt(recipientBal0), "tokensToClaim should be correct") await h.expectThrow(tbridge.claimExtraWithdraw(await accounts[2].address)) await h.advanceTime(43200) + _limit1 = await tbridge.withdrawLimit.call() + await tbridge.claimExtraWithdraw(await accounts[2].address); await h.expectThrow(tbridge.claimExtraWithdraw(await accounts[2].address)) - recipientBal = await token.balanceOf(await accounts[2].address) - assert(recipientBal == BigInt(40e18), "token balance should be correct") + recipientBal1 = await token.balanceOf(await accounts[2].address) + assert(recipientBal1 == BigInt(recipientBal0) + BigInt(_limit1), "token balance should be correct") + tokensToClaim = await tbridge.tokensToClaim(accounts[2].address) + assert(tokensToClaim == BigInt(WITHDRAW_AMOUNT) - BigInt(recipientBal1), "tokensToClaim should be correct") await h.advanceTime(43200) - await tbridge.refreshDepositLimit() - _limit = await tbridge.depositLimit() - assert(BigInt(await tbridge.depositLimitRecord()) - expectedDepositLimit == BigInt(0)); - assert(_limit == expectedDepositLimit, "deposit Limit should be correct") + + await tbridge.claimExtraWithdraw(await accounts[2].address); + await h.expectThrow(tbridge.claimExtraWithdraw(await accounts[2].address)) + recipientBal2 = await token.balanceOf(await accounts[2].address) + assert(recipientBal2 == WITHDRAW_AMOUNT, "token balance should be correct") tokensToClaim = await tbridge.tokensToClaim(accounts[2].address) assert(tokensToClaim == BigInt(0), "tokensToClaim should be correct") }) + + it("pauseBridge", async function () { + bridgeState = await tbridge.bridgeState() + assert.equal(bridgeState, 0, "bridge state should be correct") + for (let i = 0; i < 20; i++) { + await token.faucet(accounts[1].address) + } + await token.connect(accounts[1]).approve(tbridge.address, h.toWei("10000")) + await h.expectThrow(tbridge.connect(accounts[1]).pauseBridge()) // not guardian + await token.connect(accounts[1]).transfer(guardian.address, h.toWei("20000")) + await h.expectThrow(tbridge.connect(guardian).pauseBridge()) // not approved + await token.connect(guardian).approve(tbridge.address, h.toWei("1000")) + await h.expectThrow(tbridge.connect(guardian).pauseBridge()) // not enought approved + await token.connect(guardian).approve(tbridge.address, h.toWei("10000")) + await tbridge.connect(guardian).pauseBridge() + blocky = await h.getBlock() + bridgeState = await tbridge.bridgeState() + bridgeStateUpdateTime = await tbridge.bridgeStateUpdateTime() + burnedBalance = await token.balanceOf("0x000000000000000000000000000000000000dEaD") + assert.equal(bridgeState, 1, "bridge state should be correct") + assert.equal(bridgeStateUpdateTime, blocky.timestamp, "bridge state update time should be correct") + assert.equal(burnedBalance.toString(), h.toWei("10000"), "burned balance should be correct") + await token.connect(guardian).approve(tbridge.address, h.toWei("10000")) + await h.expectThrow(tbridge.connect(guardian).pauseBridge()) // already paused + await h.advanceTime(86400 * 21) + await tbridge.unpauseBridge() + await h.expectThrow(tbridge.connect(guardian).unpauseBridge()) // can't pause again + }) + + it("unpauseBridge", async function () { + await h.expectThrow(tbridge.unpauseBridge()) // not paused + for (let i = 0; i < 10; i++) { + await token.faucet(guardian.address) + } + await token.connect(guardian).approve(tbridge.address, h.toWei("10000")) + await tbridge.connect(guardian).pauseBridge() + await h.expectThrow(tbridge.unpauseBridge()) // not enough time + await h.advanceTime(86400 * 21) + await tbridge.unpauseBridge() + bridgeState = await tbridge.bridgeState() + assert.equal(bridgeState, 2, "bridge state should be correct") + await h.expectThrow(tbridge.unpauseBridge()) // already unpaused + }) + // more complex tests it("100 deposits and withdrawals", async function () { this.timeout(300000) @@ -236,11 +381,11 @@ describe("TokenBridge - Function Tests", async function () { niters = 100 depositAmount0 = h.toWei("5") depositAmount1 = h.toWei("10") - + tip = h.toWei("0") // deposits for (let i = 0; i < niters; i++) { - await tbridge.connect(accounts[0]).depositToLayer(depositAmount0, LAYER_RECIPIENT) - await tbridge.connect(accounts[1]).depositToLayer(depositAmount1, LAYER_RECIPIENT) + await tbridge.connect(accounts[0]).depositToLayer(depositAmount0, tip, LAYER_RECIPIENT) + await tbridge.connect(accounts[1]).depositToLayer(depositAmount1, tip, LAYER_RECIPIENT) await h.advanceTime(43200) } // checks @@ -331,14 +476,14 @@ describe("TokenBridge - Function Tests", async function () { attestationTimestamp ) - depositLimitBefore0 = await tbridge.depositLimit() + withdrawLimitBefore0 = await tbridge.withdrawLimit() await tbridge.withdrawFromLayer( oracleDataStruct0, currentValSetArray, sigStructArray0, withdrawId0, ) - depositLimitBefore1 = await tbridge.depositLimit() + withdrawLimitBefore1 = await tbridge.withdrawLimit() await tbridge.withdrawFromLayer( oracleDataStruct1, currentValSetArray, @@ -346,18 +491,18 @@ describe("TokenBridge - Function Tests", async function () { withdrawId1, ) - if (BigInt(depositAmount0) > BigInt(depositLimitBefore0)) { - expectedBal0 += BigInt(depositLimitBefore0) - expTokensToClaim0 += BigInt(depositAmount0) - BigInt(depositLimitBefore0) - expectedBalBridge -= BigInt(depositLimitBefore0) + if (BigInt(depositAmount0) > BigInt(withdrawLimitBefore0)) { + expectedBal0 += BigInt(withdrawLimitBefore0) + expTokensToClaim0 += BigInt(depositAmount0) - BigInt(withdrawLimitBefore0) + expectedBalBridge -= BigInt(withdrawLimitBefore0) } else { expectedBal0 += BigInt(depositAmount0) expectedBalBridge -= BigInt(depositAmount0) } - if (depositAmount1 > depositLimitBefore1) { - expectedBal1 += BigInt(depositLimitBefore1) - expTokensToClaim1 += BigInt(depositAmount1) - BigInt(depositLimitBefore1) - expectedBalBridge -= BigInt(depositLimitBefore1) + if (depositAmount1 > withdrawLimitBefore1) { + expectedBal1 += BigInt(withdrawLimitBefore1) + expTokensToClaim1 += BigInt(depositAmount1) - BigInt(withdrawLimitBefore1) + expectedBalBridge -= BigInt(withdrawLimitBefore1) } else { expectedBal1 += BigInt(depositAmount1) expectedBalBridge -= BigInt(depositAmount1) @@ -435,7 +580,8 @@ describe("TokenBridge - Function Tests", async function () { assert(BigInt(bridgeBal) == BigInt(0), "bridge bal should be correct") await token.approve(bridge2.address, h.toWei("10000")) await h.advanceTime(86400) - await bridge2.depositToLayer(h.toWei("20"), LAYER_RECIPIENT) + tip = h.toWei("0") + await bridge2.depositToLayer(h.toWei("20"), tip, LAYER_RECIPIENT) blocky1 = await h.getBlock() // formula from Tellor360: // uint256 _releasedAmount = (146.94 ether * @@ -445,7 +591,7 @@ describe("TokenBridge - Function Tests", async function () { bridgeBal = await token.balanceOf(await bridge2.address) assert(BigInt(bridgeBal) == BigInt(expectedBal), "bridge bal should be correct") await h.advanceTime(86400) - await bridge2.depositToLayer(h.toWei("20"), LAYER_RECIPIENT) + await bridge2.depositToLayer(h.toWei("20"), tip, LAYER_RECIPIENT) expectedBal = expectedBal + BigInt(h.toWei("20")) bridgeBal = await token.balanceOf(await bridge2.address) assert(BigInt(bridgeBal) == BigInt(expectedBal), "bridge bal should be correct") diff --git a/evm/test/helpers/evmHelpers.js b/evm/test/helpers/evmHelpers.js index 970658494..7481030b1 100644 --- a/evm/test/helpers/evmHelpers.js +++ b/evm/test/helpers/evmHelpers.js @@ -187,8 +187,9 @@ getOracleDataStruct = (queryId, value, timestamp, aggregatePower, previousTimest } getWithdrawValue = (_recipient, _sender, _amount) =>{ - myVal = abiCoder.encode(["address", "string", "uint256"], - [_recipient, _sender, _amount]) + myVal = abiCoder.encode(["address", "string", "uint256", "uint256"], + // tip is 0 for withdrawals + [_recipient, _sender, _amount, 0]) return myVal } diff --git a/evm/test/helpers/helpers.js b/evm/test/helpers/helpers.js index 9aa6909fc..4b4e5b361 100644 --- a/evm/test/helpers/helpers.js +++ b/evm/test/helpers/helpers.js @@ -132,7 +132,7 @@ getValsetSigs = async (timestamp, valset, checkpoint) => { getCurrentAggregateReport = async (queryId) => { const formattedQueryId = queryId.startsWith("0x") ? queryId.slice(2) : queryId; - url = "http://localhost:1317/layer/bridge/get_current_aggregate_report/" + formattedQueryId + url = "http://localhost:1317/tellor-io/layer/oracle/get_current_aggregate_report/" + formattedQueryId try { const response = await axios.get(url) agg = response.data.aggregate diff --git a/proto/layer/bridge/tx.proto b/proto/layer/bridge/tx.proto index bf682aa3f..f006b3f79 100644 --- a/proto/layer/bridge/tx.proto +++ b/proto/layer/bridge/tx.proto @@ -13,7 +13,7 @@ service Msg { option (cosmos.msg.v1.service) = true; rpc RequestAttestations(MsgRequestAttestations) returns (MsgRequestAttestationsResponse); rpc WithdrawTokens(MsgWithdrawTokens) returns (MsgWithdrawTokensResponse); - rpc ClaimDeposit(MsgClaimDepositRequest) returns (MsgClaimDepositResponse); + rpc ClaimDeposits(MsgClaimDepositsRequest) returns (MsgClaimDepositsResponse); } message MsgRequestAttestations { @@ -36,12 +36,12 @@ message MsgWithdrawTokens { message MsgWithdrawTokensResponse {} -message MsgClaimDepositRequest { +message MsgClaimDepositsRequest { option (cosmos.msg.v1.signer) = "creator"; string creator = 1; - uint64 deposit_id = 2; - uint64 index = 3; + repeated uint64 deposit_ids = 2; + repeated uint64 indices = 3; } -message MsgClaimDepositResponse {} +message MsgClaimDepositsResponse {} diff --git a/start_scripts/start_bill.sh b/start_scripts/start_bill.sh index f2a60e110..52d038b56 100755 --- a/start_scripts/start_bill.sh +++ b/start_scripts/start_bill.sh @@ -96,7 +96,7 @@ echo "$VALIDATOR_JSON" > $NODE2_HOME_DIR/config/validator.json # Stake Bill as a validator echo "Staking bill as a validator..." -./layerd tx staking create-validator ~/.layer/bill/config/validator.json --from bill --keyring-backend $KEYRING_BACKEND --keyring-dir ~/.layer/bill --chain-id $CHAIN_ID --home ~/.layer/bill --gas 300000 +./layerd tx staking create-validator ~/.layer/bill/config/validator.json --from bill --keyring-backend $KEYRING_BACKEND --keyring-dir ~/.layer/bill --chain-id $CHAIN_ID --home ~/.layer/bill --gas 300000 --fees 1000loya # Modify keyring-backend in client.toml for bill echo "Modifying keyring-backend in client.toml for bill..." diff --git a/x/bridge/autocli.go b/x/bridge/autocli.go index b3a9dc7cc..ebf3881a3 100644 --- a/x/bridge/autocli.go +++ b/x/bridge/autocli.go @@ -97,10 +97,10 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions { PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "creator"}, {ProtoField: "recipient"}, {ProtoField: "amount"}}, }, { - RpcMethod: "ClaimDeposit", - Use: "claim-deposit [creator] [deposit-id] [index]", - Short: "Execute the ClaimDeposit RPC method", - PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "creator"}, {ProtoField: "deposit_id"}, {ProtoField: "index"}}, + RpcMethod: "ClaimDeposits", + Use: "claim-deposits [creator] [deposit-ids] [indices]", + Short: "Execute the ClaimDeposits RPC method", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "creator"}, {ProtoField: "deposit_ids"}, {ProtoField: "indices"}}, }, // this line is used by ignite scaffolding # autocli/tx }, diff --git a/x/bridge/keeper/claim_deposit.go b/x/bridge/keeper/claim_deposit.go index 323676c03..b239e0870 100644 --- a/x/bridge/keeper/claim_deposit.go +++ b/x/bridge/keeper/claim_deposit.go @@ -5,7 +5,6 @@ import ( "encoding/hex" "errors" "fmt" - "math" "math/big" "time" @@ -19,7 +18,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -func (k Keeper) ClaimDeposit(ctx context.Context, depositId, reportIndex uint64) error { +func (k Keeper) ClaimDeposit(ctx context.Context, depositId, reportIndex uint64, msgSender sdk.AccAddress) error { cosmosCtx := sdk.UnwrapSDKContext(ctx) queryId, err := k.GetDepositQueryId(depositId) if err != nil { @@ -41,14 +40,17 @@ func (k Keeper) ClaimDeposit(ctx context.Context, depositId, reportIndex uint64) } else if depositClaimedStatus.Claimed { return types.ErrDepositAlreadyClaimed } - - // get total bonded tokens - totalBondedTokens, err := k.reporterKeeper.TotalReporterPower(ctx) + // get power threshold at report time + valsetTimestampBefore, err := k.GetValidatorSetTimestampBefore(ctx, uint64(aggregateTimestamp.UnixMilli())) + if err != nil { + return err + } + valsetCheckpointParams, err := k.GetValidatorCheckpointParamsFromStorage(ctx, valsetTimestampBefore) if err != nil { return err } - powerThreshold := int64(math.Round(float64(totalBondedTokens.Int64()) * 2 / 3)) - if aggregate.ReporterPower*layer.PowerReduction.Int64() < powerThreshold { + powerThreshold := valsetCheckpointParams.PowerThreshold + if aggregate.ReporterPower < powerThreshold { return types.ErrInsufficientReporterPower } // ensure can't claim deposit until report is old enough @@ -56,7 +58,7 @@ func (k Keeper) ClaimDeposit(ctx context.Context, depositId, reportIndex uint64) return types.ErrReportTooYoung } - recipient, amount, err := k.DecodeDepositReportValue(ctx, aggregate.AggregateValue) + recipient, amount, tip, err := k.DecodeDepositReportValue(ctx, aggregate.AggregateValue) if err != nil { k.Logger(ctx).Error("claimDeposit", "error", fmt.Errorf("failed to decode deposit report value, err: %w", err)) return fmt.Errorf("%s: %w", types.ErrInvalidDepositReportValue.Error(), err) @@ -74,7 +76,17 @@ func (k Keeper) ClaimDeposit(ctx context.Context, depositId, reportIndex uint64) return err } - if err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, recipient, amount); err != nil { + claimAmount := amount + if tip.IsAllPositive() { + claimAmount = amount.Sub(tip...) + err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, msgSender, tip) + if err != nil { + k.Logger(ctx).Error("claimDeposit", "error", fmt.Errorf("failed to send coins, err: %w", err)) + return err + } + } + + if err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, recipient, claimAmount); err != nil { k.Logger(ctx).Error("claimDeposit", "error", fmt.Errorf("failed to send coins, err: %w", err)) return err } @@ -131,54 +143,53 @@ func (k Keeper) GetDepositQueryId(depositId uint64) ([]byte, error) { return queryId, nil } -// replicate solidity decoding, abi.decode(reportValue, (address ethSender, string layerRecipient, uint256 amount)) -func (k Keeper) DecodeDepositReportValue(ctx context.Context, reportValue string) (recipient sdk.AccAddress, amount sdk.Coins, err error) { +// replicate solidity decoding, abi.decode(reportValue, (address ethSender, string layerRecipient, uint256 amount, uint256 tip)) +func (k Keeper) DecodeDepositReportValue(ctx context.Context, reportValue string) (recipient sdk.AccAddress, amount, tip sdk.Coins, err error) { // prepare decoding AddressType, err := abi.NewType("address", "", nil) if err != nil { - return nil, sdk.Coins{}, err + return nil, sdk.Coins{}, sdk.Coins{}, err } Uint256Type, err := abi.NewType("uint256", "", nil) if err != nil { - return nil, sdk.Coins{}, err + return nil, sdk.Coins{}, sdk.Coins{}, err } StringType, err := abi.NewType("string", "", nil) if err != nil { - return nil, sdk.Coins{}, err + return nil, sdk.Coins{}, sdk.Coins{}, err } - reportValueArgs := abi.Arguments{ {Type: AddressType}, {Type: StringType}, {Type: Uint256Type}, + {Type: Uint256Type}, } - // decode report value reportValueBytes, err := hex.DecodeString(reportValue) if err != nil { k.Logger(ctx).Error("@decodeDepositReportValue", "error", fmt.Errorf("failed to decode report value, err: %w", err)) - return nil, sdk.Coins{}, err + return nil, sdk.Coins{}, sdk.Coins{}, err } reportValueDecoded, err := reportValueArgs.Unpack(reportValueBytes) if err != nil { k.Logger(ctx).Error("@decodeDepositReportValue", "error", fmt.Errorf("failed to decode report value, err: %w", err)) - return nil, sdk.Coins{}, err + return nil, sdk.Coins{}, sdk.Coins{}, err } - recipientString := reportValueDecoded[1].(string) amountBigInt := reportValueDecoded[2].(*big.Int) - + tipBigInt := reportValueDecoded[3].(*big.Int) // convert layer recipient to cosmos address layerRecipientAddress, err := sdk.AccAddressFromBech32(recipientString) if err != nil { k.Logger(ctx).Error("@decodeDepositReportValue", "error", fmt.Errorf("failed to convert layer recipient to cosmos address, err: %w", err)) - return nil, sdk.Coins{}, err + return nil, sdk.Coins{}, sdk.Coins{}, err } - amountDecimalConverted := amountBigInt.Div(amountBigInt, big.NewInt(1e12)) - + tipDecimalConverted := tipBigInt.Div(tipBigInt, big.NewInt(1e12)) amountCoin := sdk.NewInt64Coin(layer.BondDenom, amountDecimalConverted.Int64()) amountCoins := sdk.NewCoins(amountCoin) + tipCoin := sdk.NewInt64Coin(layer.BondDenom, tipDecimalConverted.Int64()) + tipCoins := sdk.NewCoins(tipCoin) - return layerRecipientAddress, amountCoins, nil + return layerRecipientAddress, amountCoins, tipCoins, nil } diff --git a/x/bridge/keeper/claim_deposit_test.go b/x/bridge/keeper/claim_deposit_test.go index d9969ca8f..427a3f01a 100644 --- a/x/bridge/keeper/claim_deposit_test.go +++ b/x/bridge/keeper/claim_deposit_test.go @@ -33,58 +33,66 @@ func TestDecodeDepositReportValue(t *testing.T) { {Type: AddressType}, {Type: StringType}, {Type: Uint256Type}, + {Type: Uint256Type}, } ethAddress := common.HexToAddress("0x3386518F7ab3eb51591571adBE62CF94540EAd29") layerAddressString := simtestutil.CreateIncrementalAccounts(1)[0].String() amountAggregate := big.NewInt(1 * 1e12) // 1 loya, 0.00001 trb - reportValueArgsEncoded, err := reportValueArgs.Pack(ethAddress, layerAddressString, amountAggregate) + tipAmount := big.NewInt(1 * 1e12) + reportValueArgsEncoded, err := reportValueArgs.Pack(ethAddress, layerAddressString, amountAggregate, tipAmount) require.NoError(t, err) reportValueString := hex.EncodeToString(reportValueArgsEncoded) - recipient, amount, err := k.DecodeDepositReportValue(ctx, reportValueString) + recipient, amount, tip, err := k.DecodeDepositReportValue(ctx, reportValueString) require.Equal(t, recipient.String(), layerAddressString) require.Equal(t, amount.AmountOf("loya").BigInt(), amountAggregate.Div(amountAggregate, big.NewInt(1e12))) + require.Equal(t, tip.AmountOf("loya").BigInt(), tipAmount.Div(tipAmount, big.NewInt(1e12))) require.NoError(t, err) // decode big numbers amountAggregate = big.NewInt(1).Mul(big.NewInt(10), big.NewInt(1e18)) // 10 trb - reportValueArgsEncoded, err = reportValueArgs.Pack(ethAddress, layerAddressString, amountAggregate) + tipAmount = big.NewInt(0) + reportValueArgsEncoded, err = reportValueArgs.Pack(ethAddress, layerAddressString, amountAggregate, tipAmount) require.NoError(t, err) reportValueString = hex.EncodeToString(reportValueArgsEncoded) - recipient, amount, err = k.DecodeDepositReportValue(ctx, reportValueString) + recipient, amount, tip, err = k.DecodeDepositReportValue(ctx, reportValueString) require.Equal(t, recipient.String(), layerAddressString) require.Equal(t, amount.AmountOf("loya").BigInt(), amountAggregate.Div(amountAggregate, big.NewInt(1e12))) + require.Equal(t, tip.AmountOf("loya").BigInt(), tipAmount.Div(tipAmount, big.NewInt(1e12))) require.NoError(t, err) amountAggregate = big.NewInt(1).Mul(big.NewInt(1_000), big.NewInt(1e18)) // 1,000 trb - reportValueArgsEncoded, err = reportValueArgs.Pack(ethAddress, layerAddressString, amountAggregate) + reportValueArgsEncoded, err = reportValueArgs.Pack(ethAddress, layerAddressString, amountAggregate, tipAmount) require.NoError(t, err) reportValueString = hex.EncodeToString(reportValueArgsEncoded) - recipient, amount, err = k.DecodeDepositReportValue(ctx, reportValueString) + recipient, amount, tip, err = k.DecodeDepositReportValue(ctx, reportValueString) require.Equal(t, recipient.String(), layerAddressString) require.Equal(t, amount.AmountOf("loya").BigInt(), amountAggregate.Div(amountAggregate, big.NewInt(1e12))) + require.Equal(t, tip.AmountOf("loya").BigInt(), tipAmount.Div(tipAmount, big.NewInt(1e12))) require.NoError(t, err) amountAggregate = big.NewInt(1).Mul(big.NewInt(10_000), big.NewInt(1e18)) // 10,000 trb - reportValueArgsEncoded, err = reportValueArgs.Pack(ethAddress, layerAddressString, amountAggregate) + reportValueArgsEncoded, err = reportValueArgs.Pack(ethAddress, layerAddressString, amountAggregate, tipAmount) require.NoError(t, err) reportValueString = hex.EncodeToString(reportValueArgsEncoded) - recipient, amount, err = k.DecodeDepositReportValue(ctx, reportValueString) + recipient, amount, tip, err = k.DecodeDepositReportValue(ctx, reportValueString) require.Equal(t, recipient.String(), layerAddressString) require.Equal(t, amount.AmountOf("loya").BigInt(), amountAggregate.Div(amountAggregate, big.NewInt(1e12))) + require.Equal(t, tip.AmountOf("loya").BigInt(), tipAmount.Div(tipAmount, big.NewInt(1e12))) require.NoError(t, err) amountAggregate = big.NewInt(1).Mul(big.NewInt(1_000_000), big.NewInt(1e18)) // 1,000,000 trb - reportValueArgsEncoded, err = reportValueArgs.Pack(ethAddress, layerAddressString, amountAggregate) + reportValueArgsEncoded, err = reportValueArgs.Pack(ethAddress, layerAddressString, amountAggregate, tipAmount) require.NoError(t, err) reportValueString = hex.EncodeToString(reportValueArgsEncoded) - recipient, amount, err = k.DecodeDepositReportValue(ctx, reportValueString) + recipient, amount, tip, err = k.DecodeDepositReportValue(ctx, reportValueString) require.Equal(t, recipient.String(), layerAddressString) require.Equal(t, amount.AmountOf("loya").BigInt(), amountAggregate.Div(amountAggregate, big.NewInt(1e12))) + require.Equal(t, tip.AmountOf("loya").BigInt(), tipAmount.Div(tipAmount, big.NewInt(1e12))) require.NoError(t, err) } @@ -94,11 +102,11 @@ func TestDecodeDepositReportValueInvalidReport(t *testing.T) { require.NotNil(t, ctx) badString := "0x" - _, _, err := k.DecodeDepositReportValue(ctx, badString) + _, _, _, err := k.DecodeDepositReportValue(ctx, badString) require.Error(t, err) emptyString := "" - _, _, err = k.DecodeDepositReportValue(ctx, emptyString) + _, _, _, err = k.DecodeDepositReportValue(ctx, emptyString) require.Error(t, err) AddressType, err := abi.NewType("address", "", nil) @@ -155,7 +163,7 @@ func TestGetDepositQueryId(t *testing.T) { } func TestClaimDeposit(t *testing.T) { - k, _, bk, ok, rk, _, ctx := setupKeeper(t) + k, _, bk, ok, _, _, ctx := setupKeeper(t) require.NotNil(t, k) require.NotNil(t, ctx) sdkCtx := sdk.UnwrapSDKContext(ctx) @@ -184,19 +192,23 @@ func TestClaimDeposit(t *testing.T) { QueryId: queryId, AggregateValue: reportValueString, AggregateReportIndex: int64(0), - ReporterPower: int64(67), + ReporterPower: int64(68), } + powerThreshold := uint64(67) + validatorTimestamp := uint64(aggregateTimestamp.UnixMilli() - 1) + valSetHash := []byte("valSetHash") + _, err = k.CalculateValidatorSetCheckpoint(ctx, powerThreshold, validatorTimestamp, valSetHash) + require.NoError(t, err) sdkCtx = sdkCtx.WithBlockTime(sdkCtx.BlockTime().Add(13 * time.Hour)) - recipient, amount, err := k.DecodeDepositReportValue(ctx, reportValueString) - totalBondedTokens := math.NewInt(100) + recipient, amount, _, err := k.DecodeDepositReportValue(ctx, reportValueString) ok.On("GetAggregateByIndex", sdkCtx, queryId, uint64(aggregate.AggregateReportIndex)).Return(aggregate, aggregateTimestamp, err) - rk.On("TotalReporterPower", sdkCtx).Return(totalBondedTokens, err) bk.On("MintCoins", sdkCtx, bridgetypes.ModuleName, amount).Return(err) bk.On("SendCoinsFromModuleToAccount", sdkCtx, bridgetypes.ModuleName, recipient, amount).Return(err) depositId := uint64(0) reportIndex := uint64(0) - err = k.ClaimDeposit(sdkCtx, depositId, reportIndex) + msgSender := simtestutil.CreateIncrementalAccounts(2)[1] + err = k.ClaimDeposit(sdkCtx, depositId, reportIndex, msgSender) require.NoError(t, err) depositClaimedResult, err := k.DepositIdClaimedMap.Get(sdkCtx, depositId) require.NoError(t, err) @@ -213,7 +225,8 @@ func TestClaimDepositNilAggregate(t *testing.T) { currentTime := time.Now() ok.On("GetAggregateByIndex", sdkCtx, queryId, uint64(0)).Return(nil, currentTime, nil) - err := k.ClaimDeposit(ctx, 0, 0) + msgSender := simtestutil.CreateIncrementalAccounts(1)[0] + err := k.ClaimDeposit(ctx, 0, 0, msgSender) require.ErrorContains(t, err, "no aggregate found") } @@ -250,8 +263,9 @@ func TestClaimDepositFlaggedAggregate(t *testing.T) { ReporterPower: int64(90 * 1e6), Flagged: true, } + msgSender := simtestutil.CreateIncrementalAccounts(2)[1] sdkCtx = sdkCtx.WithBlockTime(sdkCtx.BlockTime().Add(13 * time.Hour)) - recipient, amount, err := k.DecodeDepositReportValue(ctx, reportValueString) + recipient, amount, _, err := k.DecodeDepositReportValue(ctx, reportValueString) totalBondedTokens := math.NewInt(100 * 1e6) ok.On("GetAggregateByIndex", sdkCtx, queryId, uint64(aggregate.AggregateReportIndex)).Return(aggregate, aggregateTimestamp, err) rk.On("TotalReporterPower", sdkCtx).Return(totalBondedTokens, err) @@ -260,12 +274,12 @@ func TestClaimDepositFlaggedAggregate(t *testing.T) { depositId := uint64(0) reportIndex := uint64(0) - err = k.ClaimDeposit(sdkCtx, depositId, reportIndex) + err = k.ClaimDeposit(sdkCtx, depositId, reportIndex, msgSender) require.ErrorContains(t, err, "aggregate flagged") } func TestClaimDepositNotEnoughPower(t *testing.T) { - k, _, bk, ok, rk, _, ctx := setupKeeper(t) + k, _, bk, ok, _, _, ctx := setupKeeper(t) require.NotNil(t, k) require.NotNil(t, ctx) sdkCtx := sdk.UnwrapSDKContext(ctx) @@ -295,24 +309,28 @@ func TestClaimDepositNotEnoughPower(t *testing.T) { QueryId: queryId, AggregateValue: reportValueString, AggregateReportIndex: int64(0), - ReporterPower: int64(66), + ReporterPower: int64(65), } + powerThreshold := uint64(67) + validatorTimestamp := uint64(aggregateTimestamp.UnixMilli() - 1) + valSetHash := []byte("valSetHash") + _, err = k.CalculateValidatorSetCheckpoint(ctx, powerThreshold, validatorTimestamp, valSetHash) + require.NoError(t, err) + msgSender := simtestutil.CreateIncrementalAccounts(2)[1] sdkCtx = sdkCtx.WithBlockTime(sdkCtx.BlockTime().Add(13 * time.Hour)) - recipient, amount, err := k.DecodeDepositReportValue(ctx, reportValueString) - totalBondedTokens := math.NewInt(100 * 1e6) + recipient, amount, _, err := k.DecodeDepositReportValue(ctx, reportValueString) ok.On("GetAggregateByIndex", sdkCtx, queryId, uint64(aggregate.AggregateReportIndex)).Return(aggregate, aggregateTimestamp, err) - rk.On("TotalReporterPower", sdkCtx).Return(totalBondedTokens, err) bk.On("MintCoins", sdkCtx, bridgetypes.ModuleName, amount).Return(err) bk.On("SendCoinsFromModuleToAccount", sdkCtx, bridgetypes.ModuleName, recipient, amount).Return(err) depositId := uint64(0) reportIndex := uint64(0) - err = k.ClaimDeposit(sdkCtx, depositId, reportIndex) + err = k.ClaimDeposit(sdkCtx, depositId, reportIndex, msgSender) require.ErrorContains(t, err, "insufficient reporter power") } func TestClaimDepositReportTooYoung(t *testing.T) { - k, _, bk, ok, rk, _, ctx := setupKeeper(t) + k, _, bk, ok, _, _, ctx := setupKeeper(t) require.NotNil(t, k) require.NotNil(t, ctx) sdkCtx := sdk.UnwrapSDKContext(ctx) @@ -341,24 +359,28 @@ func TestClaimDepositReportTooYoung(t *testing.T) { QueryId: queryId, AggregateValue: reportValueString, AggregateReportIndex: int64(0), - ReporterPower: int64(90 * 1e6), + ReporterPower: int64(68), } + powerThreshold := uint64(67) + validatorTimestamp := uint64(aggregateTimestamp.UnixMilli() - 1) + valSetHash := []byte("valSetHash") + _, err = k.CalculateValidatorSetCheckpoint(ctx, powerThreshold, validatorTimestamp, valSetHash) + require.NoError(t, err) + msgSender := simtestutil.CreateIncrementalAccounts(2)[1] sdkCtx = sdkCtx.WithBlockTime(sdkCtx.BlockTime().Add(11 * time.Hour)) - recipient, amount, err := k.DecodeDepositReportValue(ctx, reportValueString) - totalBondedTokens := math.NewInt(100 * 1e6) + recipient, amount, _, err := k.DecodeDepositReportValue(ctx, reportValueString) ok.On("GetAggregateByIndex", sdkCtx, queryId, uint64(aggregate.AggregateReportIndex)).Return(aggregate, aggregateTimestamp, err) - rk.On("TotalReporterPower", sdkCtx).Return(totalBondedTokens, err) bk.On("MintCoins", sdkCtx, bridgetypes.ModuleName, amount).Return(err) bk.On("SendCoinsFromModuleToAccount", sdkCtx, bridgetypes.ModuleName, recipient, amount).Return(err) depositId := uint64(0) reportIndex := uint64(0) - err = k.ClaimDeposit(sdkCtx, depositId, reportIndex) + err = k.ClaimDeposit(sdkCtx, depositId, reportIndex, msgSender) require.ErrorContains(t, err, "report too young") } func TestClaimDepositSpam(t *testing.T) { - k, _, bk, ok, rk, _, ctx := setupKeeper(t) + k, _, bk, ok, _, _, ctx := setupKeeper(t) require.NotNil(t, k) require.NotNil(t, ctx) sdkCtx := sdk.UnwrapSDKContext(ctx) @@ -387,19 +409,23 @@ func TestClaimDepositSpam(t *testing.T) { QueryId: queryId, AggregateValue: reportValueString, AggregateReportIndex: int64(0), - ReporterPower: int64(67), + ReporterPower: int64(68), } + powerThreshold := uint64(67) + validatorTimestamp := uint64(aggregateTimestamp.UnixMilli() - 1) + valSetHash := []byte("valSetHash") + _, err = k.CalculateValidatorSetCheckpoint(ctx, powerThreshold, validatorTimestamp, valSetHash) + require.NoError(t, err) + msgSender := simtestutil.CreateIncrementalAccounts(2)[1] sdkCtx = sdkCtx.WithBlockTime(sdkCtx.BlockTime().Add(13 * time.Hour)) - recipient, amount, err := k.DecodeDepositReportValue(ctx, reportValueString) - totalBondedTokens := math.NewInt(100) + recipient, amount, _, err := k.DecodeDepositReportValue(ctx, reportValueString) ok.On("GetAggregateByIndex", sdkCtx, queryId, uint64(aggregate.AggregateReportIndex)).Return(aggregate, aggregateTimestamp, err) - rk.On("TotalReporterPower", sdkCtx).Return(totalBondedTokens, err) bk.On("MintCoins", sdkCtx, bridgetypes.ModuleName, amount).Return(err) bk.On("SendCoinsFromModuleToAccount", sdkCtx, bridgetypes.ModuleName, recipient, amount).Return(err) depositId := uint64(0) reportIndex := uint64(0) - err = k.ClaimDeposit(sdkCtx, depositId, reportIndex) + err = k.ClaimDeposit(sdkCtx, depositId, reportIndex, msgSender) require.NoError(t, err) depositClaimedResult, err := k.DepositIdClaimedMap.Get(sdkCtx, depositId) require.NoError(t, err) @@ -408,7 +434,7 @@ func TestClaimDepositSpam(t *testing.T) { attempts := 0 for attempts < 100 { attempts++ - err = k.ClaimDeposit(sdkCtx, depositId, reportIndex) + err = k.ClaimDeposit(sdkCtx, depositId, reportIndex, msgSender) require.ErrorContains(t, err, "deposit already claimed") } } diff --git a/x/bridge/keeper/keeper.go b/x/bridge/keeper/keeper.go index 3c32f1bd4..b04844dd5 100644 --- a/x/bridge/keeper/keeper.go +++ b/x/bridge/keeper/keeper.go @@ -159,6 +159,7 @@ func (k Keeper) GetCurrentValidatorSetEVMCompatible(ctx context.Context) (*types // function for loading last saved bridge validator set and comparing it to current set func (k Keeper) CompareAndSetBridgeValidators(ctx context.Context) (bool, error) { // load current validator set in EVM compatible format + currentValidatorSetEVMCompatible, err := k.GetCurrentValidatorSetEVMCompatible(ctx) if err != nil { k.Logger(ctx).Info("No current validator set found") @@ -180,9 +181,14 @@ func (k Keeper) CompareAndSetBridgeValidators(ctx context.Context) (bool, error) } return false, err } - if bytes.Equal(k.cdc.MustMarshal(&lastSavedBridgeValidators), k.cdc.MustMarshal(currentValidatorSetEVMCompatible)) { + stale, err := k.LastSavedValidatorSetStale(ctx) + if err != nil { + k.Logger(ctx).Info("Error checking if last saved validator set is stale", "error", err) + return false, err + } + if bytes.Equal(k.cdc.MustMarshal(&lastSavedBridgeValidators), k.cdc.MustMarshal(currentValidatorSetEVMCompatible)) && !stale { return false, nil - } else if k.PowerDiff(ctx, lastSavedBridgeValidators, *currentValidatorSetEVMCompatible) < 0.05 { + } else if k.PowerDiff(ctx, lastSavedBridgeValidators, *currentValidatorSetEVMCompatible) < 0.05 && !stale { return false, nil } else { err := k.BridgeValset.Set(ctx, *currentValidatorSetEVMCompatible) @@ -373,6 +379,23 @@ func (k Keeper) CalculateValidatorSetCheckpoint( return checkpoint, nil } +// check whether last saved validator set is too old (more than 2 weeks) +func (k Keeper) LastSavedValidatorSetStale(ctx context.Context) (bool, error) { + sdkCtx := sdk.UnwrapSDKContext(ctx) + // get current block timestamp + blockTime := sdkCtx.BlockTime().Add(1 * time.Second) + valsetTimestamp, err := k.GetValidatorSetTimestampBefore(ctx, uint64(blockTime.UnixMilli())) + if err != nil { + k.Logger(ctx).Info("Error getting validator set timestamp before", "error", err) + return false, err + } + twoWeeksAgo := blockTime.Add(-2 * time.Hour * 24 * 7) + if valsetTimestamp < uint64(twoWeeksAgo.UnixMilli()) { + return true, nil + } + return false, nil +} + func (k Keeper) GetValidatorCheckpointFromStorage(ctx context.Context) (*types.ValidatorCheckpoint, error) { checkpoint, err := k.ValidatorCheckpoint.Get(ctx) if err != nil { @@ -1010,3 +1033,19 @@ func (k Keeper) GetAttestationRequestsByHeight(ctx context.Context, height uint6 func (k Keeper) GetValidatorCheckpointParamsFromStorage(ctx context.Context, timestamp uint64) (types.ValidatorCheckpointParams, error) { return k.ValidatorCheckpointParamsMap.Get(ctx, timestamp) } + +func (k Keeper) GetValidatorSetTimestampBefore(ctx context.Context, targetTimestamp uint64) (uint64, error) { + var mostRecentTimestamp uint64 + rng := new(collections.Range[uint64]).EndExclusive(targetTimestamp).Descending() + err := k.ValidatorCheckpointParamsMap.Walk(ctx, rng, func(key uint64, value types.ValidatorCheckpointParams) (bool, error) { + mostRecentTimestamp = key + return true, nil // Stop after finding the first (most recent) timestamp + }) + if err != nil { + return 0, fmt.Errorf("error walking through ValidatorCheckpointParamsMap: %w", err) + } + if mostRecentTimestamp == 0 { + return 0, fmt.Errorf("no validator set timestamp found before %d", targetTimestamp) + } + return mostRecentTimestamp, nil +} diff --git a/x/bridge/keeper/keeper_test.go b/x/bridge/keeper/keeper_test.go index 53d64ce59..80896e164 100644 --- a/x/bridge/keeper/keeper_test.go +++ b/x/bridge/keeper/keeper_test.go @@ -1184,3 +1184,101 @@ func TestEncodeOracleAttestationData(t *testing.T) { require.NoError(t, err) require.NotNil(t, res) } + +func TestGetCurrentValidatorSetTimestamp(t *testing.T) { + k, _, _, _, _, _, ctx := setupKeeper(t) + require.NotNil(t, k) + require.NotNil(t, ctx) + + testCases := []struct { + name string + setup func() + expectedTimestamp uint64 + err bool + }{ + { + name: "LatestCheckpointIdx not set", + err: true, + }, + { + name: "ValidatorCheckpointIdxMap not set", + setup: func() { + err := k.LatestCheckpointIdx.Set(ctx, types.CheckpointIdx{ + Index: 1, + }) + require.NoError(t, err) + }, + err: true, + }, + { + name: "all good", + setup: func() { + err := k.LatestCheckpointIdx.Set(ctx, types.CheckpointIdx{ + Index: 1, + }) + require.NoError(t, err) + err = k.ValidatorCheckpointIdxMap.Set(ctx, 1, types.CheckpointTimestamp{ + Timestamp: 100, + }) + require.NoError(t, err) + }, + expectedTimestamp: 100, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + if tc.setup != nil { + tc.setup() + } + timestamp, err := k.GetCurrentValidatorSetTimestamp(ctx) + if tc.err { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, timestamp, tc.expectedTimestamp) + } + }) + } +} + +func TestGetValidatorSetIndexByTimestamp(t *testing.T) { + k, _, _, _, _, _, ctx := setupKeeper(t) + require.NotNil(t, k) + require.NotNil(t, ctx) + + testCases := []struct { + name string + setup func() + expectedIndex uint64 + err bool + }{ + { + name: "ValsetTimestampToIdxMap not set", + err: true, + }, + { + name: "all good", + setup: func() { + err := k.ValsetTimestampToIdxMap.Set(ctx, 100, types.CheckpointIdx{ + Index: 1, + }) + require.NoError(t, err) + }, + expectedIndex: 1, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + if tc.setup != nil { + tc.setup() + } + index, err := k.GetValidatorSetIndexByTimestamp(ctx, 100) + if tc.err { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, index, tc.expectedIndex) + } + }) + } +} diff --git a/x/bridge/keeper/msg_server_claim_deposit.go b/x/bridge/keeper/msg_server_claim_deposit.go deleted file mode 100644 index 2e61125b0..000000000 --- a/x/bridge/keeper/msg_server_claim_deposit.go +++ /dev/null @@ -1,27 +0,0 @@ -package keeper - -import ( - "context" - "strconv" - - "github.com/tellor-io/layer/x/bridge/types" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -func (k msgServer) ClaimDeposit(goCtx context.Context, msg *types.MsgClaimDepositRequest) (*types.MsgClaimDepositResponse, error) { - sdkCtx := sdk.UnwrapSDKContext(goCtx) - - if err := k.Keeper.ClaimDeposit(sdkCtx, msg.DepositId, msg.Index); err != nil { - return nil, err - } - - sdk.UnwrapSDKContext(goCtx).EventManager().EmitEvents(sdk.Events{ - sdk.NewEvent( - "deposit_claimed", - sdk.NewAttribute("deposit_id", strconv.FormatUint(msg.DepositId, 10)), - ), - }) - - return &types.MsgClaimDepositResponse{}, nil -} diff --git a/x/bridge/keeper/msg_server_claim_deposits.go b/x/bridge/keeper/msg_server_claim_deposits.go new file mode 100644 index 000000000..63ba58d1f --- /dev/null +++ b/x/bridge/keeper/msg_server_claim_deposits.go @@ -0,0 +1,32 @@ +package keeper + +import ( + "context" + "strconv" + + "github.com/tellor-io/layer/x/bridge/types" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (k msgServer) ClaimDeposits(goCtx context.Context, msg *types.MsgClaimDepositsRequest) (*types.MsgClaimDepositsResponse, error) { + sdkCtx := sdk.UnwrapSDKContext(goCtx) + if len(msg.DepositIds) != len(msg.Indices) { + return nil, types.ErrInvalidDepositIdsAndIndicesLength + } + msgSender := sdk.MustAccAddressFromBech32(msg.Creator) + for i, depositId := range msg.DepositIds { + index := msg.Indices[i] + if err := k.Keeper.ClaimDeposit(sdkCtx, depositId, index, msgSender); err != nil { + return nil, err + } + sdk.UnwrapSDKContext(goCtx).EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + "deposit_claimed", + sdk.NewAttribute("deposit_id", strconv.FormatUint(depositId, 10)), + ), + }) + } + + return &types.MsgClaimDepositsResponse{}, nil +} diff --git a/x/bridge/keeper/msg_server_claim_deposit_test.go b/x/bridge/keeper/msg_server_claim_deposits_test.go similarity index 66% rename from x/bridge/keeper/msg_server_claim_deposit_test.go rename to x/bridge/keeper/msg_server_claim_deposits_test.go index 525cad59e..9599bfdd3 100644 --- a/x/bridge/keeper/msg_server_claim_deposit_test.go +++ b/x/bridge/keeper/msg_server_claim_deposits_test.go @@ -13,18 +13,16 @@ import ( bridgetypes "github.com/tellor-io/layer/x/bridge/types" oracletypes "github.com/tellor-io/layer/x/oracle/types" - math "cosmossdk.io/math" - simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" ) -func TestMsgClaimDeposit(t *testing.T) { - k, _, bk, ok, rk, _, ctx := setupKeeper(t) +func TestMsgClaimDeposits(t *testing.T) { + k, _, bk, ok, _, _, ctx := setupKeeper(t) msgServer := keeper.NewMsgServerImpl(k) require.Panics(t, func() { - _, err := msgServer.ClaimDeposit(ctx, nil) + _, err := msgServer.ClaimDeposits(ctx, nil) require.Error(t, err) }) @@ -40,11 +38,13 @@ func TestMsgClaimDeposit(t *testing.T) { {Type: AddressType}, {Type: StringType}, {Type: Uint256Type}, + {Type: Uint256Type}, } ethAddress := common.HexToAddress("0x3386518F7ab3eb51591571adBE62CF94540EAd29") layerAddressString := simtestutil.CreateIncrementalAccounts(1)[0].String() amountUint64 := big.NewInt(100 * 1e12) - reportValueArgsEncoded, err := reportValueArgs.Pack(ethAddress, layerAddressString, amountUint64) + tipAmountUint64 := big.NewInt(1 * 1e12) + reportValueArgsEncoded, err := reportValueArgs.Pack(ethAddress, layerAddressString, amountUint64, tipAmountUint64) require.NoError(t, err) reportValueString := hex.EncodeToString(reportValueArgsEncoded) queryId, err := k.GetDepositQueryId(0) @@ -53,23 +53,30 @@ func TestMsgClaimDeposit(t *testing.T) { QueryId: queryId, AggregateValue: reportValueString, AggregateReportIndex: int64(0), - ReporterPower: int64(67), + ReporterPower: int64(68), } + powerThreshold := uint64(67) + validatorTimestamp := uint64(aggregateTimestamp.UnixMilli() - 1) + valSetHash := []byte("valSetHash") + _, err = k.CalculateValidatorSetCheckpoint(ctx, powerThreshold, validatorTimestamp, valSetHash) + require.NoError(t, err) sdkCtx = sdkCtx.WithBlockTime(sdkCtx.BlockTime().Add(13 * time.Hour)) - recipient, amount, err := k.DecodeDepositReportValue(ctx, reportValueString) - totalBondedTokens := math.NewInt(100) + // convert ethAddress (common.Address) to sdk.Address + msgSender := sdk.AccAddress(ethAddress.Bytes()) + recipient, amount, tip, err := k.DecodeDepositReportValue(ctx, reportValueString) + claimAmount := amount.Sub(tip...) ok.On("GetAggregateByIndex", sdkCtx, queryId, uint64(aggregate.AggregateReportIndex)).Return(aggregate, aggregateTimestamp, err) - rk.On("TotalReporterPower", sdkCtx).Return(totalBondedTokens, err) bk.On("MintCoins", sdkCtx, bridgetypes.ModuleName, amount).Return(err) - bk.On("SendCoinsFromModuleToAccount", sdkCtx, bridgetypes.ModuleName, recipient, amount).Return(err) + bk.On("SendCoinsFromModuleToAccount", sdkCtx, bridgetypes.ModuleName, recipient, claimAmount).Return(err) + bk.On("SendCoinsFromModuleToAccount", sdkCtx, bridgetypes.ModuleName, msgSender, tip).Return(err) depositId := uint64(0) reportIndex := uint64(0) - result, err := msgServer.ClaimDeposit(sdkCtx, &bridgetypes.MsgClaimDepositRequest{ - Creator: ethAddress.String(), - DepositId: depositId, - Index: reportIndex, + result, err := msgServer.ClaimDeposits(sdkCtx, &bridgetypes.MsgClaimDepositsRequest{ + Creator: msgSender.String(), + DepositIds: []uint64{depositId}, + Indices: []uint64{reportIndex}, }) require.NoError(t, err) require.NotNil(t, result) diff --git a/x/bridge/keeper/query_get_current_validator_set_timestamp.go b/x/bridge/keeper/query_get_current_validator_set_timestamp.go index 8f8db5520..93e871c07 100644 --- a/x/bridge/keeper/query_get_current_validator_set_timestamp.go +++ b/x/bridge/keeper/query_get_current_validator_set_timestamp.go @@ -8,15 +8,15 @@ import ( "google.golang.org/grpc/status" ) -func (q Querier) GetValidatorSetIndexByTimestamp(ctx context.Context, req *types.QueryGetValidatorSetIndexByTimestampRequest) (*types.QueryGetValidatorSetIndexByTimestampResponse, error) { +func (q Querier) GetCurrentValidatorSetTimestamp(ctx context.Context, req *types.QueryGetCurrentValidatorSetTimestampRequest) (*types.QueryGetCurrentValidatorSetTimestampResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") } - index, err := q.k.GetValidatorSetIndexByTimestamp(ctx, uint64(req.Timestamp)) + timestamp, err := q.k.GetCurrentValidatorSetTimestamp(ctx) if err != nil { return nil, status.Error(codes.Internal, "failed to get validator checkpoint") } - return &types.QueryGetValidatorSetIndexByTimestampResponse{Index: int64(index)}, nil + return &types.QueryGetCurrentValidatorSetTimestampResponse{Timestamp: int64(timestamp)}, nil } diff --git a/x/bridge/keeper/query_get_current_validator_set_timestamp_test.go b/x/bridge/keeper/query_get_current_validator_set_timestamp_test.go new file mode 100644 index 000000000..0d0e83f36 --- /dev/null +++ b/x/bridge/keeper/query_get_current_validator_set_timestamp_test.go @@ -0,0 +1,66 @@ +package keeper_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + testkeeper "github.com/tellor-io/layer/testutil/keeper" + "github.com/tellor-io/layer/x/bridge/keeper" + "github.com/tellor-io/layer/x/bridge/types" +) + +func TestQuery_GetCurrentValidatorSetTimestamp(t *testing.T) { + k, _, _, _, _, _, ctx := testkeeper.BridgeKeeper(t) + require.NotNil(t, k) + require.NotNil(t, ctx) + q := keeper.NewQuerier(k) + + testCases := []struct { + name string + setup func() + req *types.QueryGetCurrentValidatorSetTimestampRequest + expectedTimestamp int64 + err bool + }{ + { + name: "nil request", + req: nil, + err: true, + }, + { + name: "LatestCheckpointIdx not set", + req: &types.QueryGetCurrentValidatorSetTimestampRequest{}, + err: true, + }, + { + name: "success", + setup: func() { + err := k.LatestCheckpointIdx.Set(ctx, types.CheckpointIdx{ + Index: 1, + }) + require.NoError(t, err) + err = k.ValidatorCheckpointIdxMap.Set(ctx, 1, types.CheckpointTimestamp{ + Timestamp: 100, + }) + require.NoError(t, err) + }, + req: &types.QueryGetCurrentValidatorSetTimestampRequest{}, + err: false, + expectedTimestamp: 100, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + if tc.setup != nil { + tc.setup() + } + timestamp, err := q.GetCurrentValidatorSetTimestamp(ctx, tc.req) + if tc.err { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, timestamp.Timestamp, tc.expectedTimestamp) + } + }) + } +} diff --git a/x/bridge/keeper/query_get_validator_set_index_by_timestamp.go b/x/bridge/keeper/query_get_validator_set_index_by_timestamp.go index 0cc74e252..8f8db5520 100644 --- a/x/bridge/keeper/query_get_validator_set_index_by_timestamp.go +++ b/x/bridge/keeper/query_get_validator_set_index_by_timestamp.go @@ -8,15 +8,15 @@ import ( "google.golang.org/grpc/status" ) -func (q Querier) GetCurrentValidatorSetTimestamp(ctx context.Context, req *types.QueryGetCurrentValidatorSetTimestampRequest) (*types.QueryGetCurrentValidatorSetTimestampResponse, error) { +func (q Querier) GetValidatorSetIndexByTimestamp(ctx context.Context, req *types.QueryGetValidatorSetIndexByTimestampRequest) (*types.QueryGetValidatorSetIndexByTimestampResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") } - index, err := q.k.GetCurrentValidatorSetTimestamp(ctx) + index, err := q.k.GetValidatorSetIndexByTimestamp(ctx, uint64(req.Timestamp)) if err != nil { return nil, status.Error(codes.Internal, "failed to get validator checkpoint") } - return &types.QueryGetCurrentValidatorSetTimestampResponse{Timestamp: int64(index)}, nil + return &types.QueryGetValidatorSetIndexByTimestampResponse{Index: int64(index)}, nil } diff --git a/x/bridge/keeper/query_get_validator_set_index_by_timestamp_test.go b/x/bridge/keeper/query_get_validator_set_index_by_timestamp_test.go new file mode 100644 index 000000000..7ede1f556 --- /dev/null +++ b/x/bridge/keeper/query_get_validator_set_index_by_timestamp_test.go @@ -0,0 +1,65 @@ +package keeper_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + testkeeper "github.com/tellor-io/layer/testutil/keeper" + "github.com/tellor-io/layer/x/bridge/keeper" + "github.com/tellor-io/layer/x/bridge/types" +) + +func TestQuery_GetValidatorSetIndexByTimestamp(t *testing.T) { + k, _, _, _, _, _, ctx := testkeeper.BridgeKeeper(t) + require.NotNil(t, k) + require.NotNil(t, ctx) + q := keeper.NewQuerier(k) + + testCases := []struct { + name string + setup func() + req *types.QueryGetValidatorSetIndexByTimestampRequest + expectedIndex int64 + err bool + }{ + { + name: "nil request", + req: nil, + err: true, + }, + { + name: "GetValidatorSetIndexByTimestamp not set", + req: &types.QueryGetValidatorSetIndexByTimestampRequest{ + Timestamp: 100, + }, + err: true, + }, + { + name: "success", + setup: func() { + err := k.ValsetTimestampToIdxMap.Set(ctx, 100, types.CheckpointIdx{ + Index: 1, + }) + require.NoError(t, err) + }, + req: &types.QueryGetValidatorSetIndexByTimestampRequest{ + Timestamp: 100, + }, + expectedIndex: 1, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + if tc.setup != nil { + tc.setup() + } + index, err := q.GetValidatorSetIndexByTimestamp(ctx, tc.req) + if tc.err { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, index.Index, tc.expectedIndex) + } + }) + } +} diff --git a/x/bridge/keeper/withdraw_tokens.go b/x/bridge/keeper/withdraw_tokens.go index d9516c6cd..0cbcc0d00 100644 --- a/x/bridge/keeper/withdraw_tokens.go +++ b/x/bridge/keeper/withdraw_tokens.go @@ -144,6 +144,7 @@ func (k Keeper) GetWithdrawalReportValue(amount sdk.Coin, sender sdk.AccAddress, ethAddress := common.BytesToAddress(recipient) layerAddressString := sender.String() amountUint64 := new(big.Int).SetUint64(amount.Amount.Uint64()) + tipUint64 := new(big.Int).SetUint64(0) // prepare encoding AddressType, err := abi.NewType("address", "", nil) @@ -163,10 +164,11 @@ func (k Keeper) GetWithdrawalReportValue(amount sdk.Coin, sender sdk.AccAddress, {Type: AddressType}, {Type: StringType}, {Type: Uint256Type}, + {Type: Uint256Type}, } // encode report value arguments - reportValueArgsEncoded, err := reportValueArgs.Pack(ethAddress, layerAddressString, amountUint64) + reportValueArgsEncoded, err := reportValueArgs.Pack(ethAddress, layerAddressString, amountUint64, tipUint64) if err != nil { return nil, err } diff --git a/x/bridge/module_test.go b/x/bridge/module_test.go index 6823f38e2..a2039ba4b 100644 --- a/x/bridge/module_test.go +++ b/x/bridge/module_test.go @@ -127,6 +127,15 @@ func TestEndBlock(t *testing.T) { Checkpoint: []byte("checkpoint"), }) require.NoError(t, err) + // save checkpoint params + checkpointParams := types.ValidatorCheckpointParams{ + Checkpoint: []byte("checkpoint"), + ValsetHash: []byte("validatorSetHash"), + Timestamp: timestamp.UnixMilli(), + PowerThreshold: int64(100), + } + err = k.ValidatorCheckpointParamsMap.Set(ctx, uint64(timestamp.UnixMilli()), checkpointParams) + require.NoError(t, err) ok.On("GetTimestampAfter", sdkCtx, queryId, timestamp).Return(timestampPlus1, nil) err = k.BridgeValset.Set(ctx, types.BridgeValidatorSet{ BridgeValidatorSet: []*types.BridgeValidator{ diff --git a/x/bridge/types/errors.go b/x/bridge/types/errors.go index 6813f605f..da0c00236 100644 --- a/x/bridge/types/errors.go +++ b/x/bridge/types/errors.go @@ -8,11 +8,12 @@ import ( // x/bridge module sentinel errors var ( - ErrSample = sdkerrors.Register(ModuleName, 1100, "sample error") - ErrNoAggregate = sdkerrors.Register(ModuleName, 1101, "no aggregate found") - ErrAggregateFlagged = sdkerrors.Register(ModuleName, 1102, "aggregate flagged") - ErrInsufficientReporterPower = sdkerrors.Register(ModuleName, 1103, "insufficient reporter power") - ErrReportTooYoung = sdkerrors.Register(ModuleName, 1104, "report too young") - ErrInvalidDepositReportValue = sdkerrors.Register(ModuleName, 1105, "invalid deposit report value") - ErrDepositAlreadyClaimed = sdkerrors.Register(ModuleName, 1106, "deposit already claimed") + ErrSample = sdkerrors.Register(ModuleName, 1100, "sample error") + ErrNoAggregate = sdkerrors.Register(ModuleName, 1101, "no aggregate found") + ErrAggregateFlagged = sdkerrors.Register(ModuleName, 1102, "aggregate flagged") + ErrInsufficientReporterPower = sdkerrors.Register(ModuleName, 1103, "insufficient reporter power") + ErrReportTooYoung = sdkerrors.Register(ModuleName, 1104, "report too young") + ErrInvalidDepositReportValue = sdkerrors.Register(ModuleName, 1105, "invalid deposit report value") + ErrDepositAlreadyClaimed = sdkerrors.Register(ModuleName, 1106, "deposit already claimed") + ErrInvalidDepositIdsAndIndicesLength = sdkerrors.Register(ModuleName, 1107, "invalid deposit ids and indices length") ) diff --git a/x/bridge/types/message_claim_deposit.go b/x/bridge/types/message_claim_deposit.go deleted file mode 100644 index 55119d443..000000000 --- a/x/bridge/types/message_claim_deposit.go +++ /dev/null @@ -1,49 +0,0 @@ -package types - -import ( - errorsmod "cosmossdk.io/errors" - - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" -) - -const TypeMsgClaimDeposit = "claim_deposit" - -var _ sdk.Msg = &MsgClaimDepositRequest{} - -func NewMsgClaimDepositRequest(creator string, depositId, reportIndex uint64) *MsgClaimDepositRequest { - return &MsgClaimDepositRequest{ - Creator: creator, - DepositId: depositId, - Index: reportIndex, - } -} - -func (msg *MsgClaimDepositRequest) Route() string { - return RouterKey -} - -func (msg *MsgClaimDepositRequest) Type() string { - return TypeMsgClaimDeposit -} - -func (msg *MsgClaimDepositRequest) GetSigners() []sdk.AccAddress { - creator, err := sdk.AccAddressFromBech32(msg.Creator) - if err != nil { - panic(err) - } - return []sdk.AccAddress{creator} -} - -func (msg *MsgClaimDepositRequest) GetSignBytes() []byte { - bz := ModuleCdc.MustMarshalJSON(msg) - return sdk.MustSortJSON(bz) -} - -func (msg *MsgClaimDepositRequest) ValidateBasic() error { - _, err := sdk.AccAddressFromBech32(msg.Creator) - if err != nil { - return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) - } - return nil -} diff --git a/x/bridge/types/message_claim_deposit_test.go b/x/bridge/types/message_claim_deposit_test.go deleted file mode 100644 index d1b200a60..000000000 --- a/x/bridge/types/message_claim_deposit_test.go +++ /dev/null @@ -1,59 +0,0 @@ -package types - -import ( - "testing" - - "github.com/stretchr/testify/require" - "github.com/tellor-io/layer/testutil/sample" - - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" -) - -func TestMsgClaimDeposit_NewMsgClaimDepositRequest(t *testing.T) { - addr := sample.AccAddress() - msg := NewMsgClaimDepositRequest(addr, 0, 0) - require.Equal(t, msg.Type(), "claim_deposit") - require.Equal(t, msg.Creator, addr) - require.Equal(t, msg.DepositId, uint64(0)) - require.Equal(t, msg.Index, uint64(0)) -} - -func TestMsgClaimDeposit_ValidateBasic(t *testing.T) { - tests := []struct { - name string - msg MsgClaimDepositRequest - err error - }{ - { - name: "invalid address", - msg: MsgClaimDepositRequest{ - Creator: "invalid_address", - }, - err: sdkerrors.ErrInvalidAddress, - }, - { - name: "valid address", - msg: MsgClaimDepositRequest{ - Creator: sample.AccAddress(), - }, - }, - { - name: "normal data", - msg: MsgClaimDepositRequest{ - Creator: sample.AccAddress(), - DepositId: 1, - Index: 1, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.msg.ValidateBasic() - if tt.err != nil { - require.ErrorIs(t, err, tt.err) - return - } - require.NoError(t, err) - }) - } -} diff --git a/x/bridge/types/tx.pb.go b/x/bridge/types/tx.pb.go index 2eab270f0..780e945ce 100644 --- a/x/bridge/types/tx.pb.go +++ b/x/bridge/types/tx.pb.go @@ -222,24 +222,24 @@ func (m *MsgWithdrawTokensResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgWithdrawTokensResponse proto.InternalMessageInfo -type MsgClaimDepositRequest struct { - Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty"` - DepositId uint64 `protobuf:"varint,2,opt,name=deposit_id,json=depositId,proto3" json:"deposit_id,omitempty"` - Index uint64 `protobuf:"varint,3,opt,name=index,proto3" json:"index,omitempty"` +type MsgClaimDepositsRequest struct { + Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty"` + DepositIds []uint64 `protobuf:"varint,2,rep,packed,name=deposit_ids,json=depositIds,proto3" json:"deposit_ids,omitempty"` + Indices []uint64 `protobuf:"varint,3,rep,packed,name=indices,proto3" json:"indices,omitempty"` } -func (m *MsgClaimDepositRequest) Reset() { *m = MsgClaimDepositRequest{} } -func (m *MsgClaimDepositRequest) String() string { return proto.CompactTextString(m) } -func (*MsgClaimDepositRequest) ProtoMessage() {} -func (*MsgClaimDepositRequest) Descriptor() ([]byte, []int) { +func (m *MsgClaimDepositsRequest) Reset() { *m = MsgClaimDepositsRequest{} } +func (m *MsgClaimDepositsRequest) String() string { return proto.CompactTextString(m) } +func (*MsgClaimDepositsRequest) ProtoMessage() {} +func (*MsgClaimDepositsRequest) Descriptor() ([]byte, []int) { return fileDescriptor_cb4091a52ebadfca, []int{4} } -func (m *MsgClaimDepositRequest) XXX_Unmarshal(b []byte) error { +func (m *MsgClaimDepositsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *MsgClaimDepositRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *MsgClaimDepositsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_MsgClaimDepositRequest.Marshal(b, m, deterministic) + return xxx_messageInfo_MsgClaimDepositsRequest.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -249,54 +249,54 @@ func (m *MsgClaimDepositRequest) XXX_Marshal(b []byte, deterministic bool) ([]by return b[:n], nil } } -func (m *MsgClaimDepositRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_MsgClaimDepositRequest.Merge(m, src) +func (m *MsgClaimDepositsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgClaimDepositsRequest.Merge(m, src) } -func (m *MsgClaimDepositRequest) XXX_Size() int { +func (m *MsgClaimDepositsRequest) XXX_Size() int { return m.Size() } -func (m *MsgClaimDepositRequest) XXX_DiscardUnknown() { - xxx_messageInfo_MsgClaimDepositRequest.DiscardUnknown(m) +func (m *MsgClaimDepositsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_MsgClaimDepositsRequest.DiscardUnknown(m) } -var xxx_messageInfo_MsgClaimDepositRequest proto.InternalMessageInfo +var xxx_messageInfo_MsgClaimDepositsRequest proto.InternalMessageInfo -func (m *MsgClaimDepositRequest) GetCreator() string { +func (m *MsgClaimDepositsRequest) GetCreator() string { if m != nil { return m.Creator } return "" } -func (m *MsgClaimDepositRequest) GetDepositId() uint64 { +func (m *MsgClaimDepositsRequest) GetDepositIds() []uint64 { if m != nil { - return m.DepositId + return m.DepositIds } - return 0 + return nil } -func (m *MsgClaimDepositRequest) GetIndex() uint64 { +func (m *MsgClaimDepositsRequest) GetIndices() []uint64 { if m != nil { - return m.Index + return m.Indices } - return 0 + return nil } -type MsgClaimDepositResponse struct { +type MsgClaimDepositsResponse struct { } -func (m *MsgClaimDepositResponse) Reset() { *m = MsgClaimDepositResponse{} } -func (m *MsgClaimDepositResponse) String() string { return proto.CompactTextString(m) } -func (*MsgClaimDepositResponse) ProtoMessage() {} -func (*MsgClaimDepositResponse) Descriptor() ([]byte, []int) { +func (m *MsgClaimDepositsResponse) Reset() { *m = MsgClaimDepositsResponse{} } +func (m *MsgClaimDepositsResponse) String() string { return proto.CompactTextString(m) } +func (*MsgClaimDepositsResponse) ProtoMessage() {} +func (*MsgClaimDepositsResponse) Descriptor() ([]byte, []int) { return fileDescriptor_cb4091a52ebadfca, []int{5} } -func (m *MsgClaimDepositResponse) XXX_Unmarshal(b []byte) error { +func (m *MsgClaimDepositsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *MsgClaimDepositResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *MsgClaimDepositsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_MsgClaimDepositResponse.Marshal(b, m, deterministic) + return xxx_messageInfo_MsgClaimDepositsResponse.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -306,62 +306,62 @@ func (m *MsgClaimDepositResponse) XXX_Marshal(b []byte, deterministic bool) ([]b return b[:n], nil } } -func (m *MsgClaimDepositResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_MsgClaimDepositResponse.Merge(m, src) +func (m *MsgClaimDepositsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgClaimDepositsResponse.Merge(m, src) } -func (m *MsgClaimDepositResponse) XXX_Size() int { +func (m *MsgClaimDepositsResponse) XXX_Size() int { return m.Size() } -func (m *MsgClaimDepositResponse) XXX_DiscardUnknown() { - xxx_messageInfo_MsgClaimDepositResponse.DiscardUnknown(m) +func (m *MsgClaimDepositsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgClaimDepositsResponse.DiscardUnknown(m) } -var xxx_messageInfo_MsgClaimDepositResponse proto.InternalMessageInfo +var xxx_messageInfo_MsgClaimDepositsResponse proto.InternalMessageInfo func init() { proto.RegisterType((*MsgRequestAttestations)(nil), "layer.bridge.MsgRequestAttestations") proto.RegisterType((*MsgRequestAttestationsResponse)(nil), "layer.bridge.MsgRequestAttestationsResponse") proto.RegisterType((*MsgWithdrawTokens)(nil), "layer.bridge.MsgWithdrawTokens") proto.RegisterType((*MsgWithdrawTokensResponse)(nil), "layer.bridge.MsgWithdrawTokensResponse") - proto.RegisterType((*MsgClaimDepositRequest)(nil), "layer.bridge.MsgClaimDepositRequest") - proto.RegisterType((*MsgClaimDepositResponse)(nil), "layer.bridge.MsgClaimDepositResponse") + proto.RegisterType((*MsgClaimDepositsRequest)(nil), "layer.bridge.MsgClaimDepositsRequest") + proto.RegisterType((*MsgClaimDepositsResponse)(nil), "layer.bridge.MsgClaimDepositsResponse") } func init() { proto.RegisterFile("layer/bridge/tx.proto", fileDescriptor_cb4091a52ebadfca) } var fileDescriptor_cb4091a52ebadfca = []byte{ - // 482 bytes of a gzipped FileDescriptorProto + // 495 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x53, 0xcd, 0x6e, 0xd3, 0x40, - 0x10, 0x8e, 0xfb, 0x07, 0x19, 0x22, 0x24, 0x4c, 0xa1, 0x89, 0x29, 0x6e, 0x15, 0x81, 0x80, 0x0a, - 0x76, 0x95, 0x72, 0x40, 0xe2, 0x46, 0xc3, 0xa5, 0x87, 0x5c, 0x2c, 0x24, 0xa4, 0x72, 0x40, 0xfe, - 0x19, 0xb9, 0x2b, 0x62, 0x8f, 0xbb, 0xbb, 0x2e, 0xc9, 0x0d, 0xf1, 0x04, 0x88, 0x27, 0xc9, 0x63, - 0xf4, 0xd8, 0x23, 0x27, 0x84, 0x92, 0x43, 0x5f, 0x03, 0xc5, 0xeb, 0xa4, 0x25, 0xb1, 0x5a, 0x4e, - 0xde, 0xf9, 0xe6, 0xf3, 0xcc, 0xb7, 0xdf, 0xec, 0xc0, 0x83, 0xbe, 0x3f, 0x44, 0xc9, 0x03, 0x29, - 0xa2, 0x18, 0xb9, 0x1e, 0xb0, 0x4c, 0x92, 0x26, 0xbb, 0x51, 0xc0, 0xcc, 0xc0, 0x8e, 0x1b, 0x92, - 0x4a, 0x48, 0xf1, 0xc0, 0x57, 0xc8, 0x4f, 0x3b, 0x01, 0x6a, 0xbf, 0xc3, 0x43, 0x12, 0xa9, 0x61, - 0x3b, 0x5b, 0x65, 0x3e, 0x51, 0x31, 0x3f, 0xed, 0x4c, 0x3f, 0x65, 0x62, 0x33, 0xa6, 0x98, 0x8a, - 0x23, 0x9f, 0x9e, 0x0c, 0xda, 0x1e, 0xc2, 0xc3, 0x9e, 0x8a, 0x3d, 0x3c, 0xc9, 0x51, 0xe9, 0x77, - 0x5a, 0xa3, 0xd2, 0xbe, 0x16, 0x94, 0x2a, 0xbb, 0x09, 0xb7, 0x42, 0x89, 0xbe, 0x26, 0xd9, 0xb4, - 0x76, 0xad, 0xe7, 0x75, 0x6f, 0x16, 0xda, 0x2d, 0xb8, 0x7d, 0x92, 0xa3, 0x1c, 0x7e, 0x16, 0x51, - 0x73, 0xc5, 0xa4, 0x8a, 0xf8, 0x30, 0xb2, 0xb7, 0xa1, 0xae, 0x45, 0x32, 0x2d, 0x92, 0x64, 0xcd, - 0xd5, 0x22, 0x77, 0x09, 0xbc, 0x6d, 0x7c, 0xbf, 0x18, 0xed, 0xcd, 0xca, 0xb4, 0x77, 0xc1, 0xad, - 0x6e, 0xed, 0xa1, 0xca, 0x28, 0x55, 0xd8, 0xfe, 0x69, 0xc1, 0xbd, 0x9e, 0x8a, 0x3f, 0x0a, 0x7d, - 0x1c, 0x49, 0xff, 0xeb, 0x07, 0xfa, 0x82, 0xd7, 0x0a, 0xdb, 0x86, 0xba, 0xc4, 0x50, 0x64, 0x02, - 0x53, 0x5d, 0x2a, 0xbb, 0x04, 0xec, 0x37, 0xb0, 0xe1, 0x27, 0x94, 0xa7, 0xba, 0x10, 0x76, 0x67, - 0xbf, 0xc5, 0x8c, 0x55, 0x6c, 0x6a, 0x25, 0x2b, 0xad, 0x64, 0x5d, 0x12, 0xe9, 0xc1, 0xda, 0xd9, - 0xef, 0x9d, 0x9a, 0x57, 0xd2, 0x17, 0x64, 0x3f, 0x82, 0xd6, 0x92, 0xa6, 0xb9, 0xe2, 0xbc, 0xb0, - 0xb3, 0xdb, 0xf7, 0x45, 0xf2, 0x1e, 0x33, 0x52, 0x42, 0x97, 0xf7, 0xbb, 0x46, 0xf5, 0x63, 0x80, - 0xc8, 0x70, 0x67, 0x86, 0xae, 0x79, 0xf5, 0x12, 0x39, 0x8c, 0xec, 0x4d, 0x58, 0x17, 0x69, 0x84, - 0x83, 0x42, 0xf5, 0x9a, 0x67, 0x82, 0x05, 0x4d, 0x2d, 0xd8, 0x5a, 0x6a, 0x6b, 0x14, 0xed, 0x8f, - 0x56, 0x60, 0xb5, 0xa7, 0x62, 0x5b, 0xc0, 0xfd, 0xaa, 0x29, 0x3f, 0x61, 0x57, 0x5f, 0x17, 0xab, - 0x1e, 0x88, 0xf3, 0xf2, 0x7f, 0x58, 0xb3, 0x96, 0xf6, 0x11, 0xdc, 0x5d, 0x18, 0xd9, 0xce, 0xd2, - 0xff, 0xff, 0x12, 0x9c, 0x67, 0x37, 0x10, 0xe6, 0xb5, 0x3f, 0x41, 0xe3, 0xea, 0x35, 0x2b, 0xf4, - 0x57, 0x98, 0xef, 0x3c, 0xbd, 0x81, 0x65, 0x8a, 0x3b, 0xeb, 0xdf, 0x2e, 0x46, 0x7b, 0xd6, 0x41, - 0xf7, 0x6c, 0xec, 0x5a, 0xe7, 0x63, 0xd7, 0xfa, 0x33, 0x76, 0xad, 0x1f, 0x13, 0xb7, 0x76, 0x3e, - 0x71, 0x6b, 0xbf, 0x26, 0x6e, 0xed, 0xe8, 0x45, 0x2c, 0xf4, 0x71, 0x1e, 0xb0, 0x90, 0x12, 0xae, - 0xb1, 0xdf, 0x27, 0xf9, 0x4a, 0x10, 0x37, 0x6b, 0x3b, 0x98, 0x2f, 0xee, 0x30, 0x43, 0x15, 0x6c, - 0x14, 0xfb, 0xf5, 0xfa, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xce, 0xdc, 0x16, 0xc5, 0xd5, 0x03, - 0x00, 0x00, + 0x10, 0x8e, 0x9b, 0x52, 0xc8, 0xb4, 0x20, 0x61, 0x7e, 0xea, 0x98, 0xca, 0x89, 0x22, 0x7e, 0x4a, + 0x05, 0x5e, 0xa5, 0x1c, 0x90, 0xb8, 0xd1, 0x70, 0xe9, 0x21, 0x17, 0x0b, 0x09, 0xa9, 0x07, 0x2a, + 0xff, 0x8c, 0xb6, 0x2b, 0x62, 0xaf, 0xbb, 0xb3, 0x29, 0x8d, 0xc4, 0x01, 0xf1, 0x04, 0x88, 0x27, + 0xa9, 0xc4, 0x4b, 0xf4, 0xd8, 0x23, 0x27, 0x84, 0x92, 0x43, 0x5f, 0x03, 0xc5, 0xeb, 0xa4, 0x34, + 0x89, 0x5a, 0x4e, 0xde, 0xfd, 0xbe, 0x6f, 0x67, 0xbe, 0x99, 0xf1, 0xc0, 0x83, 0x5e, 0x38, 0x40, + 0xc5, 0x22, 0x25, 0x12, 0x8e, 0x4c, 0x1f, 0xfb, 0xb9, 0x92, 0x5a, 0xda, 0x6b, 0x05, 0xec, 0x1b, + 0xd8, 0xf5, 0x62, 0x49, 0xa9, 0x24, 0x16, 0x85, 0x84, 0xec, 0xa8, 0x1d, 0xa1, 0x0e, 0xdb, 0x2c, + 0x96, 0x22, 0x33, 0x6a, 0x77, 0xbd, 0xe4, 0x53, 0xe2, 0xec, 0xa8, 0x3d, 0xfe, 0x94, 0xc4, 0x7d, + 0x2e, 0xb9, 0x2c, 0x8e, 0x6c, 0x7c, 0x32, 0x68, 0x6b, 0x00, 0x0f, 0xbb, 0xc4, 0x03, 0x3c, 0xec, + 0x23, 0xe9, 0xb7, 0x5a, 0x23, 0xe9, 0x50, 0x0b, 0x99, 0x91, 0xed, 0xc0, 0xcd, 0x58, 0x61, 0xa8, + 0xa5, 0x72, 0xac, 0xa6, 0xb5, 0x59, 0x0b, 0x26, 0x57, 0xbb, 0x0e, 0xb7, 0x0e, 0xfb, 0xa8, 0x06, + 0xfb, 0x22, 0x71, 0x96, 0x0c, 0x55, 0xdc, 0x77, 0x13, 0x7b, 0x03, 0x6a, 0x5a, 0xa4, 0xe3, 0x20, + 0x69, 0xee, 0x54, 0x0b, 0xee, 0x02, 0x78, 0xb3, 0xf6, 0xed, 0xfc, 0x64, 0x6b, 0x12, 0xa6, 0xd5, + 0x04, 0x6f, 0x71, 0xea, 0x00, 0x29, 0x97, 0x19, 0x61, 0xeb, 0x87, 0x05, 0x77, 0xbb, 0xc4, 0x3f, + 0x08, 0x7d, 0x90, 0xa8, 0xf0, 0xf3, 0x7b, 0xf9, 0x09, 0xaf, 0x34, 0xb6, 0x01, 0x35, 0x85, 0xb1, + 0xc8, 0x05, 0x66, 0xba, 0x74, 0x76, 0x01, 0xd8, 0xaf, 0x61, 0x25, 0x4c, 0x65, 0x3f, 0xd3, 0x85, + 0xb1, 0xd5, 0xed, 0xba, 0x6f, 0x5a, 0xe5, 0x8f, 0x5b, 0xe9, 0x97, 0xad, 0xf4, 0x3b, 0x52, 0x64, + 0x3b, 0xcb, 0xa7, 0xbf, 0x1b, 0x95, 0xa0, 0x94, 0xcf, 0xd8, 0x7e, 0x04, 0xf5, 0x39, 0x4f, 0x53, + 0xc7, 0x5f, 0x60, 0xbd, 0x4b, 0xbc, 0xd3, 0x0b, 0x45, 0xfa, 0x0e, 0x73, 0x49, 0x42, 0x53, 0x59, + 0xe0, 0x15, 0xb6, 0x1b, 0xb0, 0x9a, 0x18, 0xf1, 0xbe, 0x48, 0xc8, 0x59, 0x6a, 0x56, 0x37, 0x97, + 0x03, 0x28, 0xa1, 0xdd, 0xa4, 0xa8, 0x58, 0x64, 0x89, 0x88, 0x91, 0x9c, 0x6a, 0x41, 0x4e, 0xae, + 0x33, 0xd6, 0x5c, 0x70, 0xe6, 0xb3, 0x1b, 0x67, 0xdb, 0x3f, 0x97, 0xa0, 0xda, 0x25, 0x6e, 0x0b, + 0xb8, 0xb7, 0x68, 0xda, 0x8f, 0xfd, 0x7f, 0xff, 0x32, 0x7f, 0xf1, 0x60, 0xdc, 0x17, 0xff, 0xa3, + 0x9a, 0xa4, 0xb4, 0xf7, 0xe0, 0xce, 0xcc, 0xe8, 0x1a, 0x73, 0xef, 0x2f, 0x0b, 0xdc, 0x67, 0xd7, + 0x08, 0xa6, 0xb1, 0x3f, 0xc2, 0xed, 0x4b, 0x75, 0xda, 0x4f, 0xe6, 0x5e, 0x2e, 0x9a, 0x82, 0xfb, + 0xf4, 0x3a, 0x99, 0x89, 0xef, 0xde, 0xf8, 0x7a, 0x7e, 0xb2, 0x65, 0xed, 0x74, 0x4e, 0x87, 0x9e, + 0x75, 0x36, 0xf4, 0xac, 0x3f, 0x43, 0xcf, 0xfa, 0x3e, 0xf2, 0x2a, 0x67, 0x23, 0xaf, 0xf2, 0x6b, + 0xe4, 0x55, 0xf6, 0x9e, 0x73, 0xa1, 0x0f, 0xfa, 0x91, 0x1f, 0xcb, 0x94, 0x69, 0xec, 0xf5, 0xa4, + 0x7a, 0x29, 0x24, 0x33, 0x1b, 0x7c, 0x3c, 0xdd, 0xe1, 0x41, 0x8e, 0x14, 0xad, 0x14, 0xab, 0xf6, + 0xea, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x31, 0xb7, 0xd8, 0x32, 0xe0, 0x03, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -378,7 +378,7 @@ const _ = grpc.SupportPackageIsVersion4 type MsgClient interface { RequestAttestations(ctx context.Context, in *MsgRequestAttestations, opts ...grpc.CallOption) (*MsgRequestAttestationsResponse, error) WithdrawTokens(ctx context.Context, in *MsgWithdrawTokens, opts ...grpc.CallOption) (*MsgWithdrawTokensResponse, error) - ClaimDeposit(ctx context.Context, in *MsgClaimDepositRequest, opts ...grpc.CallOption) (*MsgClaimDepositResponse, error) + ClaimDeposits(ctx context.Context, in *MsgClaimDepositsRequest, opts ...grpc.CallOption) (*MsgClaimDepositsResponse, error) } type msgClient struct { @@ -407,9 +407,9 @@ func (c *msgClient) WithdrawTokens(ctx context.Context, in *MsgWithdrawTokens, o return out, nil } -func (c *msgClient) ClaimDeposit(ctx context.Context, in *MsgClaimDepositRequest, opts ...grpc.CallOption) (*MsgClaimDepositResponse, error) { - out := new(MsgClaimDepositResponse) - err := c.cc.Invoke(ctx, "/layer.bridge.Msg/ClaimDeposit", in, out, opts...) +func (c *msgClient) ClaimDeposits(ctx context.Context, in *MsgClaimDepositsRequest, opts ...grpc.CallOption) (*MsgClaimDepositsResponse, error) { + out := new(MsgClaimDepositsResponse) + err := c.cc.Invoke(ctx, "/layer.bridge.Msg/ClaimDeposits", in, out, opts...) if err != nil { return nil, err } @@ -420,7 +420,7 @@ func (c *msgClient) ClaimDeposit(ctx context.Context, in *MsgClaimDepositRequest type MsgServer interface { RequestAttestations(context.Context, *MsgRequestAttestations) (*MsgRequestAttestationsResponse, error) WithdrawTokens(context.Context, *MsgWithdrawTokens) (*MsgWithdrawTokensResponse, error) - ClaimDeposit(context.Context, *MsgClaimDepositRequest) (*MsgClaimDepositResponse, error) + ClaimDeposits(context.Context, *MsgClaimDepositsRequest) (*MsgClaimDepositsResponse, error) } // UnimplementedMsgServer can be embedded to have forward compatible implementations. @@ -433,8 +433,8 @@ func (*UnimplementedMsgServer) RequestAttestations(ctx context.Context, req *Msg func (*UnimplementedMsgServer) WithdrawTokens(ctx context.Context, req *MsgWithdrawTokens) (*MsgWithdrawTokensResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method WithdrawTokens not implemented") } -func (*UnimplementedMsgServer) ClaimDeposit(ctx context.Context, req *MsgClaimDepositRequest) (*MsgClaimDepositResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ClaimDeposit not implemented") +func (*UnimplementedMsgServer) ClaimDeposits(ctx context.Context, req *MsgClaimDepositsRequest) (*MsgClaimDepositsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ClaimDeposits not implemented") } func RegisterMsgServer(s grpc1.Server, srv MsgServer) { @@ -477,20 +477,20 @@ func _Msg_WithdrawTokens_Handler(srv interface{}, ctx context.Context, dec func( return interceptor(ctx, in, info, handler) } -func _Msg_ClaimDeposit_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MsgClaimDepositRequest) +func _Msg_ClaimDeposits_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgClaimDepositsRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(MsgServer).ClaimDeposit(ctx, in) + return srv.(MsgServer).ClaimDeposits(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/layer.bridge.Msg/ClaimDeposit", + FullMethod: "/layer.bridge.Msg/ClaimDeposits", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MsgServer).ClaimDeposit(ctx, req.(*MsgClaimDepositRequest)) + return srv.(MsgServer).ClaimDeposits(ctx, req.(*MsgClaimDepositsRequest)) } return interceptor(ctx, in, info, handler) } @@ -508,8 +508,8 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ Handler: _Msg_WithdrawTokens_Handler, }, { - MethodName: "ClaimDeposit", - Handler: _Msg_ClaimDeposit_Handler, + MethodName: "ClaimDeposits", + Handler: _Msg_ClaimDeposits_Handler, }, }, Streams: []grpc.StreamDesc{}, @@ -653,7 +653,7 @@ func (m *MsgWithdrawTokensResponse) MarshalToSizedBuffer(dAtA []byte) (int, erro return len(dAtA) - i, nil } -func (m *MsgClaimDepositRequest) Marshal() (dAtA []byte, err error) { +func (m *MsgClaimDepositsRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -663,25 +663,51 @@ func (m *MsgClaimDepositRequest) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *MsgClaimDepositRequest) MarshalTo(dAtA []byte) (int, error) { +func (m *MsgClaimDepositsRequest) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *MsgClaimDepositRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *MsgClaimDepositsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if m.Index != 0 { - i = encodeVarintTx(dAtA, i, uint64(m.Index)) + if len(m.Indices) > 0 { + dAtA3 := make([]byte, len(m.Indices)*10) + var j2 int + for _, num := range m.Indices { + for num >= 1<<7 { + dAtA3[j2] = uint8(uint64(num)&0x7f | 0x80) + num >>= 7 + j2++ + } + dAtA3[j2] = uint8(num) + j2++ + } + i -= j2 + copy(dAtA[i:], dAtA3[:j2]) + i = encodeVarintTx(dAtA, i, uint64(j2)) i-- - dAtA[i] = 0x18 + dAtA[i] = 0x1a } - if m.DepositId != 0 { - i = encodeVarintTx(dAtA, i, uint64(m.DepositId)) + if len(m.DepositIds) > 0 { + dAtA5 := make([]byte, len(m.DepositIds)*10) + var j4 int + for _, num := range m.DepositIds { + for num >= 1<<7 { + dAtA5[j4] = uint8(uint64(num)&0x7f | 0x80) + num >>= 7 + j4++ + } + dAtA5[j4] = uint8(num) + j4++ + } + i -= j4 + copy(dAtA[i:], dAtA5[:j4]) + i = encodeVarintTx(dAtA, i, uint64(j4)) i-- - dAtA[i] = 0x10 + dAtA[i] = 0x12 } if len(m.Creator) > 0 { i -= len(m.Creator) @@ -693,7 +719,7 @@ func (m *MsgClaimDepositRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } -func (m *MsgClaimDepositResponse) Marshal() (dAtA []byte, err error) { +func (m *MsgClaimDepositsResponse) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -703,12 +729,12 @@ func (m *MsgClaimDepositResponse) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *MsgClaimDepositResponse) MarshalTo(dAtA []byte) (int, error) { +func (m *MsgClaimDepositsResponse) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *MsgClaimDepositResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *MsgClaimDepositsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -785,7 +811,7 @@ func (m *MsgWithdrawTokensResponse) Size() (n int) { return n } -func (m *MsgClaimDepositRequest) Size() (n int) { +func (m *MsgClaimDepositsRequest) Size() (n int) { if m == nil { return 0 } @@ -795,16 +821,24 @@ func (m *MsgClaimDepositRequest) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } - if m.DepositId != 0 { - n += 1 + sovTx(uint64(m.DepositId)) + if len(m.DepositIds) > 0 { + l = 0 + for _, e := range m.DepositIds { + l += sovTx(uint64(e)) + } + n += 1 + sovTx(uint64(l)) + l } - if m.Index != 0 { - n += 1 + sovTx(uint64(m.Index)) + if len(m.Indices) > 0 { + l = 0 + for _, e := range m.Indices { + l += sovTx(uint64(e)) + } + n += 1 + sovTx(uint64(l)) + l } return n } -func (m *MsgClaimDepositResponse) Size() (n int) { +func (m *MsgClaimDepositsResponse) Size() (n int) { if m == nil { return 0 } @@ -1212,7 +1246,7 @@ func (m *MsgWithdrawTokensResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgClaimDepositRequest) Unmarshal(dAtA []byte) error { +func (m *MsgClaimDepositsRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1235,10 +1269,10 @@ func (m *MsgClaimDepositRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgClaimDepositRequest: wiretype end group for non-group") + return fmt.Errorf("proto: MsgClaimDepositsRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgClaimDepositRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgClaimDepositsRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -1274,42 +1308,156 @@ func (m *MsgClaimDepositRequest) Unmarshal(dAtA []byte) error { m.Creator = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field DepositId", wireType) - } - m.DepositId = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx + if wireType == 0 { + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } } - if iNdEx >= l { + m.DepositIds = append(m.DepositIds, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { return io.ErrUnexpectedEOF } - b := dAtA[iNdEx] - iNdEx++ - m.DepositId |= uint64(b&0x7F) << shift - if b < 0x80 { - break + var elementCount int + var count int + for _, integer := range dAtA[iNdEx:postIndex] { + if integer < 128 { + count++ + } + } + elementCount = count + if elementCount != 0 && len(m.DepositIds) == 0 { + m.DepositIds = make([]uint64, 0, elementCount) } + for iNdEx < postIndex { + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.DepositIds = append(m.DepositIds, v) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field DepositIds", wireType) } case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType) - } - m.Index = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx + if wireType == 0 { + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } } - if iNdEx >= l { + m.Indices = append(m.Indices, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { return io.ErrUnexpectedEOF } - b := dAtA[iNdEx] - iNdEx++ - m.Index |= uint64(b&0x7F) << shift - if b < 0x80 { - break + var elementCount int + var count int + for _, integer := range dAtA[iNdEx:postIndex] { + if integer < 128 { + count++ + } + } + elementCount = count + if elementCount != 0 && len(m.Indices) == 0 { + m.Indices = make([]uint64, 0, elementCount) + } + for iNdEx < postIndex { + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Indices = append(m.Indices, v) } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field Indices", wireType) } default: iNdEx = preIndex @@ -1332,7 +1480,7 @@ func (m *MsgClaimDepositRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgClaimDepositResponse) Unmarshal(dAtA []byte) error { +func (m *MsgClaimDepositsResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1355,10 +1503,10 @@ func (m *MsgClaimDepositResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgClaimDepositResponse: wiretype end group for non-group") + return fmt.Errorf("proto: MsgClaimDepositsResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgClaimDepositResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgClaimDepositsResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: diff --git a/x/oracle/abci_test.go b/x/oracle/abci_test.go index 6ba8d0ad1..29f46b93c 100644 --- a/x/oracle/abci_test.go +++ b/x/oracle/abci_test.go @@ -6,8 +6,10 @@ import ( "github.com/stretchr/testify/suite" "github.com/tellor-io/layer/app/config" keepertest "github.com/tellor-io/layer/testutil/keeper" + "github.com/tellor-io/layer/x/oracle" "github.com/tellor-io/layer/x/oracle/keeper" "github.com/tellor-io/layer/x/oracle/mocks" + registrytypes "github.com/tellor-io/layer/x/registry/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -39,11 +41,21 @@ func TestTestSuite(t *testing.T) { suite.Run(t, new(TestSuite)) } -// func (s *TestSuite) TestEndBlocker() { -// require := s.Require() -// k := s.oracleKeeper -// ctx := s.ctx +func (s *TestSuite) TestEndBlocker() { + require := s.Require() + k := s.oracleKeeper + ctx := s.ctx -// err := oracle.EndBlocker(ctx, k) -// require.NoError(err) -// } + query1, err := k.GetCurrentQueryInCycleList(ctx) + require.NoError(err) + require.NotNil(query1) + + s.registryKeeper.On("GetSpec", ctx, "SpotPrice").Return(registrytypes.DataSpec{}, nil) + err = oracle.EndBlocker(ctx, k) + require.NoError(err) + + query2, err := k.GetCurrentQueryInCycleList(ctx) + require.NoError(err) + require.NotNil(query2) + require.NotEqual(query1, query2) +} diff --git a/x/oracle/keeper/cycle_list.go b/x/oracle/keeper/cycle_list.go index c014524ac..d5e97c818 100644 --- a/x/oracle/keeper/cycle_list.go +++ b/x/oracle/keeper/cycle_list.go @@ -1,7 +1,6 @@ package keeper import ( - "bytes" "context" "errors" @@ -152,15 +151,3 @@ func (k Keeper) GenesisCycleList(ctx context.Context, cyclelist [][]byte) error } return nil } - -func (k Keeper) IncycleCheck(ctx context.Context, queryId []byte) (bool, error) { - peek, err := k.CyclelistSequencer.Peek(ctx) - if err != nil { - return false, err - } - cyclelist, err := k.GetCyclelist(ctx) - if err != nil { - return false, err - } - return bytes.Equal(queryId, cyclelist[peek]), nil -} diff --git a/x/oracle/keeper/cycle_list_test.go b/x/oracle/keeper/cycle_list_test.go index 8254de4b3..a79b2f51b 100644 --- a/x/oracle/keeper/cycle_list_test.go +++ b/x/oracle/keeper/cycle_list_test.go @@ -114,3 +114,18 @@ func (s *KeeperTestSuite) TestGenesisCycleList() { require.NoError(err) require.Equal(cycleList, querydataBytes) } + +func (s *KeeperTestSuite) TestGetNextCurrentQueryInCycleList() { + require := s.Require() + k := s.oracleKeeper + ctx := s.ctx + + currentQuery, err := k.GetCurrentQueryInCycleList(ctx) + require.NoError(err) + require.NotNil(currentQuery) + + query, err := k.GetNextCurrentQueryInCycleList(ctx) + require.NoError(err) + require.NotNil(query) + require.NotEqual(currentQuery, query) +} diff --git a/x/oracle/keeper/query_current_cyclelist_query_test.go b/x/oracle/keeper/query_current_cyclelist_query_test.go index 46391a6a2..8f57784ef 100644 --- a/x/oracle/keeper/query_current_cyclelist_query_test.go +++ b/x/oracle/keeper/query_current_cyclelist_query_test.go @@ -21,3 +21,18 @@ func (s *KeeperTestSuite) TestQueryCurrentCyclelist() { require.NoError(err) fmt.Println(res) } + +func (s *KeeperTestSuite) TestNextCyclelistQuery() { + require := s.Require() + ctx := s.ctx + q := s.queryClient + + // nil request + _, err := q.NextCyclelistQuery(ctx, nil) + require.ErrorContains(err, "invalid request") + + // good request + res, err := q.NextCyclelistQuery(ctx, &types.QueryNextCyclelistQueryRequest{}) + require.NoError(err) + require.NotNil(res) +} diff --git a/x/oracle/keeper/query_get_aggregated_report_test.go b/x/oracle/keeper/query_get_aggregated_report_test.go deleted file mode 100644 index 336056126..000000000 --- a/x/oracle/keeper/query_get_aggregated_report_test.go +++ /dev/null @@ -1,52 +0,0 @@ -package keeper_test - -import ( - "encoding/hex" - - "github.com/tellor-io/layer/utils" - "github.com/tellor-io/layer/x/oracle/types" - - "cosmossdk.io/collections" -) - -func (s *KeeperTestSuite) TestQueryGetAggregatedReport() { - require := s.Require() - k := s.oracleKeeper - q := s.queryClient - - // nil request - res, err := q.GetCurrentAggregateReport(s.ctx, nil) - require.ErrorContains(err, "invalid request") - require.Nil(res) - - // bad query id - req := types.QueryGetCurrentAggregateReportRequest{ - QueryId: "badqueryid", - } - res, err = q.GetCurrentAggregateReport(s.ctx, &req) - require.Error(err) - require.Nil(res) - - // good req, no reports available - qId, err := utils.QueryIDFromDataString(queryData) - require.NoError(err) - req.QueryId = hex.EncodeToString(qId) - res, err = q.GetCurrentAggregateReport(s.ctx, &req) - require.ErrorContains(err, "aggregate not found") - require.Nil(res) - - // set Aggregates collection - require.NoError(k.Aggregates.Set(s.ctx, collections.Join(qId, int64(0)), types.Aggregate{ - QueryId: qId, - AggregateValue: "100", - AggregateReporter: "reporter", - ReporterPower: 100, - })) - res, err = q.GetCurrentAggregateReport(s.ctx, &req) - require.NoError(err) - require.NotNil(res) - require.Equal(res.Aggregate.QueryId, qId) - require.Equal(res.Aggregate.AggregateValue, "100") - require.Equal(res.Aggregate.AggregateReporter, "reporter") - require.Equal(res.Aggregate.ReporterPower, int64(100)) -} diff --git a/x/oracle/keeper/query_test.go b/x/oracle/keeper/query_test.go index c7f7186f1..5d4377de1 100644 --- a/x/oracle/keeper/query_test.go +++ b/x/oracle/keeper/query_test.go @@ -1,6 +1,7 @@ package keeper_test import ( + "encoding/hex" "testing" "time" @@ -11,6 +12,9 @@ import ( "github.com/tellor-io/layer/x/oracle/types" "cosmossdk.io/collections" + "cosmossdk.io/math" + + "github.com/cosmos/cosmos-sdk/types/query" ) func TestNewQuerier(t *testing.T) { @@ -19,6 +23,48 @@ func TestNewQuerier(t *testing.T) { require.NotNil(t, q) } +func (s *KeeperTestSuite) TestQueryGetAggregatedReport() { + require := s.Require() + k := s.oracleKeeper + q := s.queryClient + + // nil request + res, err := q.GetCurrentAggregateReport(s.ctx, nil) + require.ErrorContains(err, "invalid request") + require.Nil(res) + + // bad query id + req := types.QueryGetCurrentAggregateReportRequest{ + QueryId: "badqueryid", + } + res, err = q.GetCurrentAggregateReport(s.ctx, &req) + require.Error(err) + require.Nil(res) + + // good req, no reports available + qId, err := utils.QueryIDFromDataString(queryData) + require.NoError(err) + req.QueryId = hex.EncodeToString(qId) + res, err = q.GetCurrentAggregateReport(s.ctx, &req) + require.ErrorContains(err, "aggregate not found") + require.Nil(res) + + // set Aggregates collection + require.NoError(k.Aggregates.Set(s.ctx, collections.Join(qId, int64(0)), types.Aggregate{ + QueryId: qId, + AggregateValue: "100", + AggregateReporter: "reporter", + ReporterPower: 100, + })) + res, err = q.GetCurrentAggregateReport(s.ctx, &req) + require.NoError(err) + require.NotNil(res) + require.Equal(res.Aggregate.QueryId, qId) + require.Equal(res.Aggregate.AggregateValue, "100") + require.Equal(res.Aggregate.AggregateReporter, "reporter") + require.Equal(res.Aggregate.ReporterPower, int64(100)) +} + func TestGetCurrentAggregateReport(t *testing.T) { k, _, _, _, _, ctx := testkeeper.OracleKeeper(t) require.NotNil(t, k) @@ -77,3 +123,295 @@ func TestGetCurrentAggregateReport(t *testing.T) { require.Equal(t, getCurrentAggResponse.Aggregate.AggregateReportIndex, agg.AggregateReportIndex) require.Equal(t, getCurrentAggResponse.Aggregate.Height, agg.Height) } + +func TestRetreiveData(t *testing.T) { + k, _, _, _, _, ctx := testkeeper.OracleKeeper(t) + require.NotNil(t, k) + require.NotNil(t, ctx) + + q := keeper.NewQuerier(k) + + type testCase struct { + name string + queryId string + setupFunc func() + expectedError string + } + + testCases := []testCase{ + { + name: "invalid queryId", + queryId: "z", + expectedError: "invalid queryId", + }, + { + name: "collections error", + queryId: "1234abcd", + expectedError: "collections: not found", + }, + { + name: "success", + queryId: "1234abcd", + setupFunc: func() { + qId, err := utils.QueryBytesFromString("1234abcd") + require.NoError(t, err) + require.NoError(t, k.Aggregates.Set(ctx, collections.Join(qId, int64(0)), types.Aggregate{ + QueryId: qId, + AggregateValue: "100", + AggregateReporter: "reporter", + ReporterPower: 100, + })) + }, + expectedError: "", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + if tc.setupFunc != nil { + tc.setupFunc() + } + + getDataResponse, err := q.RetrieveData(ctx, &types.QueryRetrieveDataRequest{ + QueryId: tc.queryId, + }) + + if tc.expectedError != "" { + require.ErrorContains(t, err, tc.expectedError) + require.Nil(t, getDataResponse) + } else { + require.NoError(t, err) + require.NotNil(t, getDataResponse) + + } + }) + } +} + +func (s *KeeperTestSuite) TestQuery_GetAggregateBeforeByReporter() { + require := s.Require() + // k := s.oracleKeeper + q := s.queryClient + ctx := s.ctx + + reportedAt := time.Now() + _, qId, reporter, _, err := s.CreateReportAndReportersAtTimestamp(reportedAt) + s.NoError(err) + + testCases := []struct { + name string + request *types.QueryGetAggregateBeforeByReporterRequest + expectedError string + setup func() + }{ + { + name: "nil request", + request: nil, + expectedError: "invalid request", + }, + { + name: "invalid queryId", + request: &types.QueryGetAggregateBeforeByReporterRequest{ + QueryId: "z", + }, + expectedError: "invalid query id", + }, + { + name: "success", + request: &types.QueryGetAggregateBeforeByReporterRequest{ + QueryId: hex.EncodeToString(qId), + Reporter: reporter.String(), + }, + expectedError: "", + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + res, err := q.GetAggregateBeforeByReporter(ctx, tc.request) + + if tc.expectedError != "" { + require.Error(err) + require.Contains(err.Error(), tc.expectedError) + require.Nil(res) + } else { + require.NoError(err) + require.NotNil(res) + } + }) + } +} + +func (s *KeeperTestSuite) TestGetQuery() { + require := s.Require() + k := s.oracleKeeper + q := s.queryClient + ctx := s.ctx + + tests := []struct { + name string + req *types.QueryGetQueryRequest + setup func() + wantErr bool + }{ + { + name: "Valid query", + req: &types.QueryGetQueryRequest{ + QueryId: "0x1234", + Id: 1, + }, + setup: func() { + queryData, _ := utils.QueryBytesFromString("0x1234") + require.NoError(k.Query.Set(ctx, collections.Join(queryData, uint64(1)), types.QueryMeta{ + QueryData: queryData, + Id: 1, + })) + }, + wantErr: false, + }, + { + name: "Invalid queryId", + req: &types.QueryGetQueryRequest{ + QueryId: "invalid", + Id: 1, + }, + setup: func() {}, + wantErr: true, + }, + { + name: "Query not found", + req: &types.QueryGetQueryRequest{ + QueryId: "0x5678", + Id: 1, + }, + setup: func() {}, + wantErr: true, + }, + } + + for _, tt := range tests { + s.Run(tt.name, func() { + tt.setup() + resp, err := q.GetQuery(ctx, tt.req) + if tt.wantErr { + require.Error(err) + return + } + require.NoError(err) + require.NotNil(resp) + require.NotNil(resp.Query) + }) + } +} + +func (s *KeeperTestSuite) TestTippedQueries() { + require := s.Require() + k := s.oracleKeeper + q := s.queryClient + ctx := s.ctx + + queryMeta := ReturnTestQueryMeta(math.NewInt(100)) + + cleanup := func() { + iter, err := k.Query.Iterate(ctx, nil) + require.NoError(err) + defer iter.Close() + + for ; iter.Valid(); iter.Next() { + key, err := iter.Key() + require.NoError(err) + require.NoError(k.Query.Remove(ctx, key)) + } + } + + tests := []struct { + name string + req *types.QueryTippedQueriesRequest + setup func() + err bool + expectedLen int + }{ + { + name: "nil request", + req: nil, + err: true, + }, + { + name: "empty request", + req: &types.QueryTippedQueriesRequest{}, + err: false, + expectedLen: 0, + }, + { + name: "success one tipped query", + setup: func() { + require.NoError(k.Query.Set(ctx, collections.Join(queryMeta.QueryData, uint64(1)), queryMeta)) + }, + req: &types.QueryTippedQueriesRequest{ + Pagination: &query.PageRequest{ + Offset: 0, + }, + }, + err: false, + expectedLen: 1, + }, + { + name: "success multiple tips same query", + setup: func() { + require.NoError(k.Query.Set(ctx, collections.Join(queryMeta.QueryData, uint64(1)), queryMeta)) + require.NoError(k.Query.Set(ctx, collections.Join(queryMeta.QueryData, uint64(2)), queryMeta)) + require.NoError(k.Query.Set(ctx, collections.Join(queryMeta.QueryData, uint64(3)), queryMeta)) + }, + req: &types.QueryTippedQueriesRequest{ + Pagination: &query.PageRequest{ + Offset: 0, + }, + }, + err: false, + expectedLen: 3, + }, + { + name: "success multiple tips different query", + setup: func() { + require.NoError(k.Query.Set(ctx, collections.Join(queryMeta.QueryData, uint64(1)), queryMeta)) + require.NoError(k.Query.Set(ctx, collections.Join(queryMeta.QueryData, uint64(2)), queryMeta)) + secondQueryMeta := types.QueryMeta{ + Id: 1, + Amount: math.NewInt(100), + Expiration: time.Now().Add(1 * time.Minute), + RegistrySpecTimeframe: 1 * time.Minute, + HasRevealedReports: false, + QueryData: []byte("0x4c13cd9c97dbb98f2429c101a2a8150e6c7a0ddaff6124ee176a3a411067dec0"), + QueryType: "SpotPrice", + } + require.NoError(k.Query.Set(ctx, collections.Join(secondQueryMeta.QueryData, uint64(3)), secondQueryMeta)) + require.NoError(k.Query.Set(ctx, collections.Join(secondQueryMeta.QueryData, uint64(4)), secondQueryMeta)) + }, + req: &types.QueryTippedQueriesRequest{ + Pagination: &query.PageRequest{ + Offset: 0, + }, + }, + err: false, + expectedLen: 4, + }, + } + + for _, tt := range tests { + s.Run(tt.name, func() { + cleanup() + if tt.setup != nil { + tt.setup() + } + resp, err := q.TippedQueries(ctx, tt.req) + if tt.err { + require.Error(err) + return + } else { + require.NoError(err) + require.NotNil(resp) + require.Equal(tt.expectedLen, len(resp.Queries)) + } + }) + } +} diff --git a/x/oracle/keeper/rewards_test.go b/x/oracle/keeper/rewards_test.go index d299c1919..eef70498c 100644 --- a/x/oracle/keeper/rewards_test.go +++ b/x/oracle/keeper/rewards_test.go @@ -59,7 +59,8 @@ func TestCalculateRewardAmount(t *testing.T) { math.LegacyNewDec(10 * 2).Quo(math.LegacyNewDec(110)).Mul(math.LegacyNewDec(100)), math.LegacyNewDec(20).Quo(math.LegacyNewDec(110)).Mul(math.LegacyNewDec(100)), math.LegacyNewDec(30).Quo(math.LegacyNewDec(110)).Mul(math.LegacyNewDec(100)), - math.LegacyNewDec(40).Quo(math.LegacyNewDec(110)).Mul(math.LegacyNewDec(100))}, + math.LegacyNewDec(40).Quo(math.LegacyNewDec(110)).Mul(math.LegacyNewDec(100)), + }, totalPower: 110, // 40 + 30 + 20 + (10 * 2) }, { diff --git a/x/oracle/keeper/token_bridge_deposit_test.go b/x/oracle/keeper/token_bridge_deposit_test.go index 34140e863..95ba7fefb 100644 --- a/x/oracle/keeper/token_bridge_deposit_test.go +++ b/x/oracle/keeper/token_bridge_deposit_test.go @@ -1,13 +1,16 @@ package keeper_test import ( + "fmt" "math/big" "time" "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/tellor-io/layer/testutil/sample" "github.com/tellor-io/layer/utils" "github.com/tellor-io/layer/x/oracle/types" + "cosmossdk.io/collections" "cosmossdk.io/math" ) @@ -71,3 +74,91 @@ func (s *KeeperTestSuite) TestGetTokenBridgeDeposit() { require.ErrorContains(err, types.ErrNotTokenDeposit.Error()) require.Equal(types.QueryMeta{}, res) } + +func (s *KeeperTestSuite) TestHandleBridgeDepositCommit() { + require := s.Require() + k := s.oracleKeeper + ctx := s.ctx + ctx = ctx.WithBlockTime(time.Now()) + queryId, _ := utils.QueryIDFromDataString("0x5c13cd9c97dbb98f2429c101a2a8150e6c7a0ddaff6124ee176a3a411067ded0") + + queryMeta := types.QueryMeta{ + Id: 1, + Amount: math.NewInt(100 * 1e6), + Expiration: time.Now().Add(1 * time.Minute), + RegistrySpecTimeframe: 1 * time.Minute, + HasRevealedReports: false, + QueryData: []byte("0x5c13cd9c97dbb98f2429c101a2a8150e6c7a0ddaff6124ee176a3a411067ded0"), + QueryType: "TRBBridge", + } + + testCases := []struct { + name string + setup func() + queryMeta types.QueryMeta + queryId []byte + err bool + checks func() + }{ + { + name: "tipped and window not expired", + queryMeta: queryMeta, + err: false, + }, + { + name: "tipped and window expired before offset", + queryMeta: types.QueryMeta{ + Id: 2, + Amount: math.NewInt(100 * 1e6), + Expiration: time.Now().Add(-1 * time.Minute), + RegistrySpecTimeframe: 1 * time.Minute, + HasRevealedReports: false, + QueryData: []byte("0x5c13cd9c97dbb98f2429c101a2a8150e6c7a0ddaff6124ee176a3a411067ded0"), + QueryType: "TRBBridge", + }, + err: false, + checks: func() { + query, err := k.Query.Get(ctx, collections.Join(queryId, uint64(2))) + require.NoError(err) + require.Equal(query.Expiration, ctx.BlockTime().Add(queryMeta.RegistrySpecTimeframe)) + }, + }, + { + name: "no tip and expired before blocktime", + queryMeta: types.QueryMeta{ + Id: 3, + Amount: math.NewInt(0), + Expiration: time.Now().Add(-24 * time.Hour), + RegistrySpecTimeframe: 1 * time.Minute, + HasRevealedReports: false, + QueryData: []byte("0x5c13cd9c97dbb98f2429c101a2a8150e6c7a0ddaff6124ee176a3a411067ded0"), + QueryType: "TRBBridge", + }, + err: false, + checks: func() { + query, err := k.Query.Get(ctx, collections.Join(queryId, uint64(0))) + require.NoError(err) + require.Equal(query.Expiration, ctx.BlockTime().Add(queryMeta.RegistrySpecTimeframe)) + require.Equal(query.Id, uint64(0)) + }, + }, + } + for _, tc := range testCases { + s.Run(tc.name, func() { + fmt.Println("TEST: ", tc.name) + if tc.setup != nil { + tc.setup() + } + reporterAcc := sample.AccAddressBytes() + err := k.HandleBridgeDepositCommit(ctx, queryId, tc.queryMeta, reporterAcc, "hash") + if tc.err { + require.Error(err) + } else { + require.NoError(err) + } + if tc.checks != nil { + tc.checks() + } + }) + } +} diff --git a/x/registry/keeper/dataspec_test.go b/x/registry/keeper/dataspec_test.go index ad5b74769..6b946ba33 100644 --- a/x/registry/keeper/dataspec_test.go +++ b/x/registry/keeper/dataspec_test.go @@ -3,6 +3,7 @@ package keeper_test import ( "fmt" "testing" + "time" "github.com/stretchr/testify/require" "github.com/tellor-io/layer/x/registry/types" @@ -63,6 +64,65 @@ func TestSetDataSpec(t *testing.T) { specReturn, err := k.GetSpec(unwrappedCtx, queryType) require.NoError(t, err) require.Equal(t, specReturn, dataSpec) + + // test cases where buffer window exceeds max allowed value + testCases := []struct { + name string + queryType string + dataspec types.DataSpec + expectError bool + }{ + { + name: "dataspec buffer window < max buffer window, no err", + queryType: "SPOTPRICE", + dataspec: types.DataSpec{ + DocumentHash: "hash1", + ResponseValueType: "uint256", + AggregationMethod: "weighted-median", + Registrar: "creator1", + ReportBufferWindow: time.Duration(20) * 24 * time.Hour, // 20 days + }, + expectError: false, + }, + { + name: "dataspec buffer window > max buffer window, err", + queryType: "SPOTPRICE", + dataspec: types.DataSpec{ + DocumentHash: "hash2", + ResponseValueType: "uint256", + AggregationMethod: "weighted-median", + Registrar: "creator1", + ReportBufferWindow: time.Duration(22) * 24 * time.Hour, // 22 days + }, + expectError: true, + }, + { + name: "dataspec buffer window = max buffer window, no err", + queryType: "SPOTPRICE", + dataspec: types.DataSpec{ + DocumentHash: "hash3", + ResponseValueType: "uint256", + AggregationMethod: "weighted-median", + Registrar: "creator1", + ReportBufferWindow: time.Duration(21) * 24 * time.Hour, // 21 days + }, + expectError: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := k.SetDataSpec(sdk.UnwrapSDKContext(ctx), tc.queryType, tc.dataspec) + if tc.expectError { + require.Error(t, err) + } else { + require.NoError(t, err) + specReturn, err := k.GetSpec(sdk.UnwrapSDKContext(ctx), tc.queryType) + require.NoError(t, err) + require.Equal(t, specReturn, tc.dataspec) + } + }) + } } func TestHasDataSpec(t *testing.T) { @@ -90,3 +150,91 @@ func TestHasDataSpec(t *testing.T) { require.NoError(t, err) require.Equal(t, specReturn, true) } + +func TestMaxReportBufferWindow(t *testing.T) { + ms, ctx, k := setupMsgServer(t) + require.NotNil(t, ms) + require.NotNil(t, ctx) + require.NotNil(t, k) + params, err := k.GetParams(sdk.UnwrapSDKContext(ctx)) + require.NoError(t, err) + require.Equal(t, params.MaxReportBufferWindow, time.Duration(21)*time.Hour*24) // default is 21 days + + // Test cases + testCases := []struct { + name string + bufferWindow time.Duration + expectedWindow time.Duration + expectError bool + setup func() + }{ + { + name: "Set and get 1 hr buffer window", + bufferWindow: time.Duration(3600) * time.Second, + expectedWindow: time.Duration(3600) * time.Second, + expectError: false, + setup: func() { + err := k.SetParams(sdk.UnwrapSDKContext(ctx), types.Params{MaxReportBufferWindow: time.Duration(3600) * time.Second}) + require.NoError(t, err) + }, + }, + { + name: "Set and get zero buffer window", + bufferWindow: time.Duration(0) * time.Second, + expectedWindow: time.Duration(0) * time.Second, + expectError: false, + setup: func() { + err := k.SetParams(sdk.UnwrapSDKContext(ctx), types.Params{MaxReportBufferWindow: time.Duration(0) * time.Second}) + require.NoError(t, err) + }, + }, + { + name: "Update existing buffer window to 2 hrs", + bufferWindow: time.Duration(7200) * time.Second, + expectedWindow: time.Duration(7200) * time.Second, + expectError: false, + setup: func() { + err := k.SetParams(sdk.UnwrapSDKContext(ctx), types.Params{MaxReportBufferWindow: time.Duration(7200) * time.Second}) + require.NoError(t, err) + }, + }, + { + name: "Set to 21 days", + bufferWindow: time.Duration(21) * 24 * time.Hour, + expectedWindow: time.Duration(21) * 24 * time.Hour, + expectError: false, + setup: func() { + err := k.SetParams(sdk.UnwrapSDKContext(ctx), types.Params{MaxReportBufferWindow: time.Duration(21) * 24 * time.Hour}) + require.NoError(t, err) + }, + }, + { + name: "Set to 63 days", + bufferWindow: time.Duration(63) * 24 * time.Hour, + expectedWindow: time.Duration(63) * 24 * time.Hour, + expectError: false, + setup: func() { + err := k.SetParams(sdk.UnwrapSDKContext(ctx), types.Params{MaxReportBufferWindow: time.Duration(63) * 24 * time.Hour}) + require.NoError(t, err) + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + // Set the buffer window + if tc.setup != nil { + tc.setup() + } + // Get the buffer window + paramsWindow, err := k.MaxReportBufferWindow(sdk.UnwrapSDKContext(ctx)) + + if tc.expectError { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, tc.expectedWindow, paramsWindow) + } + }) + } +} diff --git a/x/registry/keeper/query_params_test.go b/x/registry/keeper/query_params_test.go index 58abc9582..5d0ca97f3 100644 --- a/x/registry/keeper/query_params_test.go +++ b/x/registry/keeper/query_params_test.go @@ -11,10 +11,14 @@ import ( func TestParamsQuery(t *testing.T) { keeper, _, _, ctx := testkeeper.RegistryKeeper(t) + querier := rk.NewQuerier(keeper) + + res, err := querier.Params(ctx, nil) + require.Error(t, err) + require.Nil(t, res) params := types.DefaultParams() require.NoError(t, keeper.SetParams(ctx, params)) - querier := rk.NewQuerier(keeper) response, err := querier.Params(ctx, &types.QueryParamsRequest{}) require.NoError(t, err) require.Equal(t, &types.QueryParamsResponse{Params: params}, response) diff --git a/x/reporter/keeper/query_test.go b/x/reporter/keeper/query_test.go index 623817b05..426b8fba0 100644 --- a/x/reporter/keeper/query_test.go +++ b/x/reporter/keeper/query_test.go @@ -2,6 +2,7 @@ package keeper_test import ( "testing" + "time" "github.com/stretchr/testify/require" "github.com/tellor-io/layer/testutil/sample" @@ -82,3 +83,94 @@ func TestSpaceAvailableByReporter(t *testing.T) { require.NoError(t, err) require.Equal(t, res.SpaceAvailable, int32(90)) } + +func TestAllowedAmountExpiration(t *testing.T) { + k, _, _, _, ctx, _ := setupKeeper(t) + querier := keeper.NewQuerier(k) + ctx = ctx.WithBlockTime(time.Now()) + + expiration := ctx.BlockTime().Add(1) + require.NoError(t, k.Tracker.Set(ctx, types.StakeTracker{Expiration: &expiration, Amount: math.NewInt(1000)})) + + res, err := querier.AllowedAmountExpiration(ctx, &types.QueryAllowedAmountExpirationRequest{}) + require.NoError(t, err) + require.Equal(t, res.Expiration, ctx.BlockTime().Add(1).UnixMilli()) +} + +func TestAvailableTips(t *testing.T) { + k, _, _, _, ctx, _ := setupKeeper(t) + querier := keeper.NewQuerier(k) + require := require.New(t) + + selectorAddr := sample.AccAddressBytes() + + cleanup := func() { + iter, err := k.SelectorTips.Iterate(ctx, nil) + require.NoError(err) + defer iter.Close() + + for ; iter.Valid(); iter.Next() { + key, err := iter.Key() + require.NoError(err) + require.NoError(k.SelectorTips.Remove(ctx, key)) + } + } + + testCases := []struct { + name string + setup func() + req *types.QueryAvailableTipsRequest + err bool + expected math.LegacyDec + }{ + { + name: "nil request", + req: nil, + err: true, + }, + { + name: "no tips", + req: &types.QueryAvailableTipsRequest{SelectorAddress: selectorAddr.String()}, + err: true, + expected: math.LegacyDec(math.NewInt(0)), + }, + { + name: "one tip", + setup: func() { + err := k.SelectorTips.Set(ctx, selectorAddr, math.LegacyDec(math.NewInt(100))) + require.NoError(err) + }, + req: &types.QueryAvailableTipsRequest{SelectorAddress: selectorAddr.String()}, + err: false, + expected: math.LegacyDec(math.NewInt(100)), + }, + { + name: "amount changes", + setup: func() { + err := k.SelectorTips.Set(ctx, selectorAddr, math.LegacyDec(math.NewInt(100))) + require.NoError(err) + err = k.SelectorTips.Set(ctx, selectorAddr, math.LegacyDec(math.NewInt(200))) + require.NoError(err) + }, + req: &types.QueryAvailableTipsRequest{SelectorAddress: selectorAddr.String()}, + err: false, + expected: math.LegacyDec(math.NewInt(200)), + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + cleanup() + + if tc.setup != nil { + tc.setup() + } + res, err := querier.AvailableTips(ctx, tc.req) + if tc.err { + require.Error(err) + } else { + require.NoError(err) + require.Equal(tc.expected, res.AvailableTips) + } + }) + } +}