-
Notifications
You must be signed in to change notification settings - Fork 23
Conversation
Added a stub of the provide redemption signature monitoring process. Also, implemented an events log which will be needed at later stage.
Implemented the main part of the redemption signature action.
# Conflicts: # pkg/extensions/tbtc/tbtc.go
} | ||
|
||
return fmt.Errorf( | ||
"could not find signature for digest: [%v]", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Worth confirming at some point if the digest is logged in a human-readable form this way.
Implemented almost all elements of the provide redemption proof action. Also, some code refactoring has been done by the way.
if err != nil { | ||
return nil, err | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hate to say that but I think we need to block this function here for some time (6-12 blocks) and check the chain before we signal the monitoring goroutine to stop. In case of a chain reorganizaion, we may get an event, stop monitoring, but the final chain state may not include the transaction with the redemption signature provided. In this case, our monitoring goroutine should act. I am not sure yet how it impacts the timeouts and exponential backoff for retries.
The same comment applies to all monitoringStopFn
implementations.
If this suggestion does not lead to changing the code structure significantly - and I think it does not - I am fine with just leaving a TODO here and addressing this and all other monitoringStopFn
implementations in a separate PR. Leaving the decision to you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd vote for a separate PR. This one is already big enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, let's just leave a TODO for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Handled in #591 but I'll this discussion open here until that PR is reviewed and merged.
pkg/extensions/tbtc/tbtc.go
Outdated
|
||
redemptionRequestedEvents, err := t.chain.PastDepositRedemptionRequestedEvents( | ||
depositAddress, | ||
0, // TODO: Should be something better that 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could make all clients deployed against Infura unhappy. As far as I know, they allow to reach no more than 1000 blocks in the past and assuming each block takes 15sec on average to mine, this is just 250 minutes back.
If there is no workaround, without seriously sacrificing code quality, we are fine. Just raising a concern.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, the approach presented here is the safest and simplest one. We can cache incoming events as an alternative but given event duplications, chain reorgs and stuff, I want to avoid caching as it strongly complicates the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had to think more about it and load entire context into my brain. More thoughts on that:
-
We need duplicate event filtering for
monitoringStartFn
. The monitoring we should go with could be a time cache with a relatively short expiration time informing about the fact we triggered action X for deposit Y. If we know there is a pending X:Y monitoring, we do not start a new one. It is not yet clear to me what the expiration time should be but I guess the time needed to mine 6-12 blocks should be enough.I think this approach is better than e.g. filtering out events by digest or any other property, as it's aligned with the approach proposed currently for
actFn
, and this way, we do not need to care about forks and two different events for the same notification in the competing branches. -
We should not wait for any confirmations in
monitoringStartFn
as there is a chance we'll lose events frommonitoringStopFn
. If we are not already monitoring X:Y, let's start a goroutine immediately. -
We should wait for 6-12 block confirmations in
monitoringStopFn
before we decide to stop the monitoring routine. -
I like we are stateless
actFn
and we don't care about the particular event instance but we are oriented in the context of deposit and monitoring of a certain state transition. -
Once we act in
actFn
we should wait for 6-12 blocks and check the state of the deposit. We need to make sure our transaction has enough confirmations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added the link to this discussion to the TODOs section where I listed all the things related to events deduplication, reorgs etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leaving this discussion open until all follow-up PRs addressing those issues are reviewed and merged.
@pdyraga added the unit tests and addressed all comments! I'm ready for the next look. |
@@ -20,7 +20,7 @@ require ( | |||
github.com/ipfs/go-log v1.0.4 | |||
github.com/keep-network/keep-common v1.2.1-0.20201020114759-19c123cbd4f4 | |||
github.com/keep-network/keep-core v1.3.0 | |||
github.com/keep-network/tbtc v1.1.1-0.20201020115551-5f9077c74826 | |||
github.com/keep-network/tbtc v1.1.1-0.20201026093513-cb9246987718 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We still need to implement a solution in keep-common
for a workaround in keep-network/tbtc#740 before merging this PR, right? Otherwise, we would end up with a situation where keep-ecdsa
master would not build against tbtc
master.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, we don't have to do anything in keep-common
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't we need generators for eventlog? From the description of the referenced PR:
Added a TBTCSystemEventLog allowing to access past events emitted by the TBTCSystem contract. This is a temporary workaround because contract bindings generated by the keep-common generator don't support this feature yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We just need the abi
file which is already generated and tracked by the VCS.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do need to implement a change to the generator in keep-common
so that it generates TBTCSystemEventLog
, correct?
Let me put it this way:
We build tBTC go package from scratch:
- we remove all generated files from
pkg/chain/ethereum/gen
- we do
go generate ./...
there - we push a new version
Then we build keep-ecdsa
:
- we update a dependency to
tbtc
- we run
go build
My understanding is that the compilation will fail because TBTCSystemEventLog
will not be there.
In other words, we are depending on a file that should be generated but it's not generated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not quite. Eventually, we should extend the existing keep-common
generator in that way it generates the Filter*
methods straight into the TBTCSystem
binding struct. TBTCSystemEventLog
is just a temporary workaround created manually without using the generator. It is also tracked by VCS similarly as the regular bindings. So, when we build tBTC package from scratch we shouldn't delete anything. We should only run go generate ./...
to capture possible contract changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. So just to be clear - I am absolutely fine with merging this PR having TBTCSystemEventLog
created manually just like now but I do not want to release a new version before we have this file generated or having Filter*
methods generated into TBTCSystem
struct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll leave this discussion open until the proper solution is implemented. I do not want to block this PR, though.
if err != nil { | ||
return nil, err | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, let's just leave a TODO for now.
pkg/extensions/tbtc/tbtc.go
Outdated
|
||
redemptionRequestedEvents, err := t.chain.PastDepositRedemptionRequestedEvents( | ||
depositAddress, | ||
0, // TODO: Should be something better that 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had to think more about it and load entire context into my brain. More thoughts on that:
-
We need duplicate event filtering for
monitoringStartFn
. The monitoring we should go with could be a time cache with a relatively short expiration time informing about the fact we triggered action X for deposit Y. If we know there is a pending X:Y monitoring, we do not start a new one. It is not yet clear to me what the expiration time should be but I guess the time needed to mine 6-12 blocks should be enough.I think this approach is better than e.g. filtering out events by digest or any other property, as it's aligned with the approach proposed currently for
actFn
, and this way, we do not need to care about forks and two different events for the same notification in the competing branches. -
We should not wait for any confirmations in
monitoringStartFn
as there is a chance we'll lose events frommonitoringStopFn
. If we are not already monitoring X:Y, let's start a goroutine immediately. -
We should wait for 6-12 block confirmations in
monitoringStopFn
before we decide to stop the monitoring routine. -
I like we are stateless
actFn
and we don't care about the particular event instance but we are oriented in the context of deposit and monitoring of a certain state transition. -
Once we act in
actFn
we should wait for 6-12 blocks and check the state of the deposit. We need to make sure our transaction has enough confirmations.
const maxActAttempts = 3 | ||
const ( | ||
maxActAttempts = 3 | ||
pastEventsLookbackBlocks = 10000 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why don't we pass the block number from which the monitoring started to actFn
? We can get the block number from the event in monitoringStartFn
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is possible but I'm afraid this can lead to some problems in the future. I'm not sure if we can safely rely on blocks numbers taken from events due to some weird things which may happen like event duplications or chain reorgs. Also, this will work for all actions but provideRedemptionProof
which should look in the past beyond the monitoring start block. Taking those concerns in account, I think the safest and simplest way is just start from block current - 10k
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can leave it like that for now. A little concerned about how much it costs to scan 10k previous blocks for operators using 3rd party Ethereum providers who charge by compute unit but we can revise in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC, it's always one eth_getLogs
call if we are talking about the number of requests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, though it sometimes does not matter if it's just one call but how expensive was to compute a respose for this call.
Refs: #574
Depends on: #580
Depends on: keep-network/tbtc#740
This pull request expands the TBTC extension by adding two new actions specific to the deposit redemption flow.
Here is a brief summary of both actions:
ProvideRedemptionSignature
actionRedemptionRequested
event. That event is emitted either byrequestRedemption
orincreaseRedemptionFee
contract methods.GotRedemptionSignature
orRedeemed
event occurs for the observed deposit. This means eitherprovideRedemptionSignature
orprovideRedemptionProof
has been called by someone else.provideRedemptionSignature
action once the deposit is close to exceeding the redemption signature timeout.ProvideRedemptionProof
actionGotRedemptionSignature
event. This event occurs onceprovideRedemptionSignature
contract method is called.RedemptionRequested
orRedeemed
event occurs for the observed deposit. These events can be emitted byincreaseRedemptionFee
orprovideRedemptionProof
respectively.increaseRedemptionFee
action once the deposit is close to exceeding the redemption proof timeout. This part will be extended soon by adding the ability of submitting the redemption proof directy if the BTC transaction exists.