Commit bc663a4f authored by Tei Im's avatar Tei Im

Record min/max inclusion block for channel

parent 768cb10d
...@@ -25,6 +25,13 @@ type channel struct { ...@@ -25,6 +25,13 @@ type channel struct {
pendingTransactions map[txID]txData pendingTransactions map[txID]txData
// Set of confirmed txID -> inclusion block. For determining if the channel is timed out // Set of confirmed txID -> inclusion block. For determining if the channel is timed out
confirmedTransactions map[txID]eth.BlockID confirmedTransactions map[txID]eth.BlockID
// True if confirmed TX list is updated. Set to false after updated min/max inclusion blocks.
confirmedTxUpdated bool
// Inclusion block number of first confirmed TX
minInclusionBlock uint64
// Inclusion block number of last confirmed TX
maxInclusionBlock uint64
} }
func newChannel(log log.Logger, metr metrics.Metricer, cfg ChannelConfig, rcfg *rollup.Config) (*channel, error) { func newChannel(log log.Logger, metr metrics.Metricer, cfg ChannelConfig, rcfg *rollup.Config) (*channel, error) {
...@@ -74,31 +81,30 @@ func (s *channel) TxConfirmed(id txID, inclusionBlock eth.BlockID) (bool, []*typ ...@@ -74,31 +81,30 @@ func (s *channel) TxConfirmed(id txID, inclusionBlock eth.BlockID) (bool, []*typ
} }
delete(s.pendingTransactions, id) delete(s.pendingTransactions, id)
s.confirmedTransactions[id] = inclusionBlock s.confirmedTransactions[id] = inclusionBlock
s.confirmedTxUpdated = true
s.channelBuilder.FramePublished(inclusionBlock.Number) s.channelBuilder.FramePublished(inclusionBlock.Number)
// If this channel timed out, put the pending blocks back into the local saved blocks // If this channel timed out, put the pending blocks back into the local saved blocks
// and then reset this state so it can try to build a new channel. // and then reset this state so it can try to build a new channel.
if s.isTimedOut() { if s.isTimedOut() {
s.metr.RecordChannelTimedOut(s.ID()) s.metr.RecordChannelTimedOut(s.ID())
s.log.Warn("Channel timed out", "id", s.ID()) s.log.Warn("Channel timed out", "id", s.ID(), "min_inclusion_block", s.minInclusionBlock, "max_inclusion_block", s.maxInclusionBlock)
return true, s.channelBuilder.Blocks() return true, s.channelBuilder.Blocks()
} }
// If we are done with this channel, record that. // If we are done with this channel, record that.
if s.isFullySubmitted() { if s.isFullySubmitted() {
s.metr.RecordChannelFullySubmitted(s.ID()) s.metr.RecordChannelFullySubmitted(s.ID())
s.log.Info("Channel is fully submitted", "id", s.ID()) s.log.Info("Channel is fully submitted", "id", s.ID(), "min_inclusion_block", s.minInclusionBlock, "max_inclusion_block", s.maxInclusionBlock)
return true, nil return true, nil
} }
return false, nil return false, nil
} }
// pendingChannelIsTimedOut returns true if submitted channel has timed out. // updateInclusionBlocks finds the first & last confirmed tx and saves its inclusion numbers
// A channel has timed out if the difference in L1 Inclusion blocks between func (s *channel) updateInclusionBlocks() {
// the first & last included block is greater than or equal to the channel timeout. if len(s.confirmedTransactions) == 0 || !s.confirmedTxUpdated {
func (s *channel) isTimedOut() bool { return
if len(s.confirmedTransactions) == 0 {
return false
} }
// If there are confirmed transactions, find the first + last confirmed block numbers // If there are confirmed transactions, find the first + last confirmed block numbers
min := uint64(math.MaxUint64) min := uint64(math.MaxUint64)
...@@ -111,11 +117,24 @@ func (s *channel) isTimedOut() bool { ...@@ -111,11 +117,24 @@ func (s *channel) isTimedOut() bool {
max = inclusionBlock.Number max = inclusionBlock.Number
} }
} }
return max-min >= s.cfg.ChannelTimeout s.minInclusionBlock = min
s.maxInclusionBlock = max
s.confirmedTxUpdated = false
}
// pendingChannelIsTimedOut returns true if submitted channel has timed out.
// A channel has timed out if the difference in L1 Inclusion blocks between
// the first & last included block is greater than or equal to the channel timeout.
func (s *channel) isTimedOut() bool {
// Update min/max inclusion blocks for timeout check
s.updateInclusionBlocks()
return s.maxInclusionBlock-s.minInclusionBlock >= s.cfg.ChannelTimeout
} }
// pendingChannelIsFullySubmitted returns true if the channel has been fully submitted. // pendingChannelIsFullySubmitted returns true if the channel has been fully submitted.
func (s *channel) isFullySubmitted() bool { func (s *channel) isFullySubmitted() bool {
// Update min/max inclusion blocks for timeout check
s.updateInclusionBlocks()
return s.IsFull() && len(s.pendingTransactions)+s.PendingFrames() == 0 return s.IsFull() && len(s.pendingTransactions)+s.PendingFrames() == 0
} }
......
...@@ -41,6 +41,7 @@ func TestChannelTimeout(t *testing.T) { ...@@ -41,6 +41,7 @@ func TestChannelTimeout(t *testing.T) {
// To avoid other methods clearing state // To avoid other methods clearing state
channel.confirmedTransactions[frameID{frameNumber: 0}] = eth.BlockID{Number: 0} channel.confirmedTransactions[frameID{frameNumber: 0}] = eth.BlockID{Number: 0}
channel.confirmedTransactions[frameID{frameNumber: 1}] = eth.BlockID{Number: 99} channel.confirmedTransactions[frameID{frameNumber: 1}] = eth.BlockID{Number: 99}
channel.confirmedTxUpdated = true
// Since the ChannelTimeout is 100, the // Since the ChannelTimeout is 100, the
// pending channel should not be timed out // pending channel should not be timed out
...@@ -54,6 +55,7 @@ func TestChannelTimeout(t *testing.T) { ...@@ -54,6 +55,7 @@ func TestChannelTimeout(t *testing.T) {
}] = eth.BlockID{ }] = eth.BlockID{
Number: 101, Number: 101,
} }
channel.confirmedTxUpdated = true
// Now the pending channel should be timed out // Now the pending channel should be timed out
timeout = channel.isTimedOut() timeout = channel.isTimedOut()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment