Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Eventlog contract calls time.Now() #2376

Open
jeffallen opened this issue Sep 17, 2020 · 9 comments
Open

Eventlog contract calls time.Now() #2376

jeffallen opened this issue Sep 17, 2020 · 9 comments
Assignees
Projects

Comments

@jeffallen
Copy link
Contributor

Contracts must be time invariant, but eventlog is not.

See also #1331.

@jeffallen jeffallen added this to TODO in Cothority via automation Sep 17, 2020
@pierluca pierluca moved this from TODO to WIP in Cothority Sep 18, 2020
@ineiti
Copy link
Member

ineiti commented Sep 22, 2020

You can use GetCurrentBlockTimestamp from here:

GetCurrentBlockTimestamp() int64

An example is here:

tr, ok := rst.(byzcoin.TimeReader)

@pierluca
Copy link
Contributor

pierluca commented Sep 23, 2020

@ineiti @jeffallen

My understanding is that event logs could be accepted only between GetCurrentBlockTimestamp() (- a few seconds) as lower bound and GetCurrentBlockTimestamp() + config.BlockInterval as upper bound.

However, I have doubts concerning how BlockInterval is defined.
My understanding is that it's used as a timeout for the generation of a single block.

However, on the following line, the magic number "4" is used as a multiplicative factor to create a window larger than BlockInterval to validate a block. What does that 4 represent? Is BlockInterval a hard timeout on the creation of a new block or is 4*BlockInterval ?

cothority/byzcoin/service.go

Lines 2171 to 2178 in 63a2ff9

window := 4 * config.BlockInterval
if window < minTimestampWindow {
window = minTimestampWindow
}
t1 := time.Now().Add(window)
ts := time.Unix(0, header.Timestamp)
if ts.After(t1) {
log.Errorf("timestamp for new block is later than time.Now + 4*config."+

The BlockInterval parameter itself seems to be undocumented:

cothority/byzcoin/proto.go

Lines 167 to 170 in 63a2ff9

// ChainConfig stores all the configuration information for one skipchain. It
// will be stored under the key [32]byte{} in the tree.
type ChainConfig struct {
BlockInterval time.Duration

I'm happy to document it once this is clarified.

@ineiti
Copy link
Member

ineiti commented Sep 23, 2020

Yes, documenting would be good ;)

Historically, blockinterval was the time the leader spent between a new block has been generated, and the time it asked the other nodes if there are any new transactions pending. Which made two blocks appear about twice the blockInterval in case there was a continuous stream of transactions.

Lately I changed the protocol to #2321, so that the nodes directly forward all transactions to the leader, who queues them up and creates blocks as long as there are transactions in the queue.

So now theblockInterval is more used as a maximum propagation time.

The magic 4 is an experimental value that allows for blocks to be created within 4 * blockInterval. This allows for some clock-skew between the nodes, as well as network propagation and contract-execution-time.

@pierluca
Copy link
Contributor

@ineiti
Am I then correct in understanding that there's no upper bound in how long it may take for a new block to be added to the blockchain, provided the participants in the blockchain do not desire to carry out some operation on it?
Rephrasing: there's no heartbeat on the ledger itself, merely (I imagine) at the network level?

@ineiti
Copy link
Member

ineiti commented Sep 23, 2020

The basic assumption is that at least 2f+1 out of 3f+1 participants follow the protocol. So as long as only f participants or less try to delay or withhold their signature, all should be fine.

If the leader is byzantine (faulty or malicious), there will be a leader-rotation until a leader is found who successfully gets a block signed.

So there is no heartbeat. If a node tries to get a transaction signed, and there is a timeout, he will propose to re-elect the leader.

@pierluca
Copy link
Contributor

pierluca commented Sep 23, 2020

That is clear.

I rather meant that, in my understanding, in the absence of activity (e.g. an instruction being sent by a client), no blocks are added. That is, there's no guarantee that no more than X [units of time] have passed since a block was last added to the ledger.

Basically, if a cothority was active, but has been idle for the last month and everything is stable (all nodes continuously online, no failures, etc.), the latest block on the ledger will be from a month ago. Correct?

It seems reasonable, I'm just trying to proceed with few assumptions as I am not yet familiar with the codebase.

@ineiti
Copy link
Member

ineiti commented Sep 24, 2020

Yes, there are no 'filler' blocks that are sent with an empty list of transactions. Although the statistics at https://stats.c4dt.org produce about 10 blocks an hour.

@ineiti
Copy link
Member

ineiti commented Sep 24, 2020

See also #2378

@pierluca pierluca mentioned this issue Sep 28, 2020
10 tasks
@ineiti
Copy link
Member

ineiti commented Jan 4, 2021

Bump @pierluca ?

@ineiti ineiti moved this from WIP to BUG in Cothority Apr 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Cothority
  
BUG
Development

No branches or pull requests

3 participants