2020-08-05 17:40:09 +00:00
|
|
|
package drivers
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/filecoin-project/go-address"
|
|
|
|
"github.com/filecoin-project/lotus/chain/types"
|
|
|
|
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
|
|
|
vtypes "github.com/filecoin-project/oni/tvx/chain/types"
|
|
|
|
)
|
|
|
|
|
|
|
|
type TipSetMessageBuilder struct {
|
|
|
|
driver *TestDriver
|
|
|
|
|
|
|
|
bbs []*BlockBuilder
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewTipSetMessageBuilder(testDriver *TestDriver) *TipSetMessageBuilder {
|
|
|
|
return &TipSetMessageBuilder{
|
|
|
|
driver: testDriver,
|
|
|
|
bbs: nil,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *TipSetMessageBuilder) WithBlockBuilder(bb *BlockBuilder) *TipSetMessageBuilder {
|
|
|
|
t.bbs = append(t.bbs, bb)
|
|
|
|
return t
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *TipSetMessageBuilder) Apply() vtypes.ApplyTipSetResult {
|
|
|
|
result := t.apply()
|
|
|
|
|
|
|
|
t.Clear()
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *TipSetMessageBuilder) ApplyAndValidate() vtypes.ApplyTipSetResult {
|
|
|
|
result := t.apply()
|
|
|
|
|
|
|
|
t.validateResult(result)
|
|
|
|
|
|
|
|
t.Clear()
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
|
|
|
func (tb *TipSetMessageBuilder) apply() vtypes.ApplyTipSetResult {
|
|
|
|
var blks []vtypes.BlockMessagesInfo
|
|
|
|
for _, b := range tb.bbs {
|
|
|
|
blks = append(blks, b.build())
|
|
|
|
}
|
|
|
|
result, err := tb.driver.applier.ApplyTipSetMessages(tb.driver.ExeCtx.Epoch, blks, tb.driver.Randomness())
|
2020-08-06 16:57:15 +00:00
|
|
|
require.NoError(T, err)
|
2020-08-05 17:40:09 +00:00
|
|
|
|
|
|
|
//t.driver.StateTracker.TrackResult(result)
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
|
|
|
func (tb *TipSetMessageBuilder) validateResult(result vtypes.ApplyTipSetResult) {
|
|
|
|
expected := []ExpectedResult{}
|
|
|
|
for _, b := range tb.bbs {
|
|
|
|
expected = append(expected, b.expectedResults...)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(result.Receipts) > len(expected) {
|
2020-08-06 16:57:15 +00:00
|
|
|
T.Fatalf("ApplyTipSetMessages returned more result than expected. Expected: %d, Actual: %d", len(expected), len(result.Receipts))
|
2020-08-05 17:40:09 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
for i := range result.Receipts {
|
|
|
|
if tb.driver.Config.ValidateExitCode() {
|
2020-08-06 16:57:15 +00:00
|
|
|
assert.Equal(T, expected[i].ExitCode, result.Receipts[i].ExitCode, "Message Number: %d Expected ExitCode: %s Actual ExitCode: %s", i, expected[i].ExitCode.Error(), result.Receipts[i].ExitCode.Error())
|
2020-08-05 17:40:09 +00:00
|
|
|
}
|
|
|
|
if tb.driver.Config.ValidateReturnValue() {
|
2020-08-06 16:57:15 +00:00
|
|
|
assert.Equal(T, expected[i].ReturnVal, result.Receipts[i].ReturnValue, "Message Number: %d Expected ReturnValue: %v Actual ReturnValue: %v", i, expected[i].ReturnVal, result.Receipts[i].ReturnValue)
|
2020-08-05 17:40:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *TipSetMessageBuilder) Clear() {
|
|
|
|
t.bbs = nil
|
|
|
|
}
|
|
|
|
|
|
|
|
type BlockBuilder struct {
|
|
|
|
TD *TestDriver
|
|
|
|
|
|
|
|
miner address.Address
|
|
|
|
ticketCount int64
|
|
|
|
|
|
|
|
secpMsgs []*types.SignedMessage
|
|
|
|
blsMsgs []*types.Message
|
|
|
|
|
|
|
|
expectedResults []ExpectedResult
|
|
|
|
}
|
|
|
|
|
|
|
|
type ExpectedResult struct {
|
|
|
|
ExitCode exitcode.ExitCode
|
|
|
|
ReturnVal []byte
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewBlockBuilder(td *TestDriver, miner address.Address) *BlockBuilder {
|
|
|
|
return &BlockBuilder{
|
|
|
|
TD: td,
|
|
|
|
miner: miner,
|
|
|
|
ticketCount: 1,
|
|
|
|
secpMsgs: nil,
|
|
|
|
blsMsgs: nil,
|
|
|
|
expectedResults: nil,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bb *BlockBuilder) addResult(code exitcode.ExitCode, retval []byte) {
|
|
|
|
bb.expectedResults = append(bb.expectedResults, ExpectedResult{
|
|
|
|
ExitCode: code,
|
|
|
|
ReturnVal: retval,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bb *BlockBuilder) WithBLSMessageOk(blsMsg *types.Message) *BlockBuilder {
|
|
|
|
bb.blsMsgs = append(bb.blsMsgs, blsMsg)
|
|
|
|
bb.addResult(exitcode.Ok, EmptyReturnValue)
|
|
|
|
return bb
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bb *BlockBuilder) WithBLSMessageDropped(blsMsg *types.Message) *BlockBuilder {
|
|
|
|
bb.blsMsgs = append(bb.blsMsgs, blsMsg)
|
|
|
|
return bb
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bb *BlockBuilder) WithBLSMessageAndCode(bm *types.Message, code exitcode.ExitCode) *BlockBuilder {
|
|
|
|
bb.blsMsgs = append(bb.blsMsgs, bm)
|
|
|
|
bb.addResult(code, EmptyReturnValue)
|
|
|
|
return bb
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bb *BlockBuilder) WithBLSMessageAndRet(bm *types.Message, retval []byte) *BlockBuilder {
|
|
|
|
bb.blsMsgs = append(bb.blsMsgs, bm)
|
|
|
|
bb.addResult(exitcode.Ok, retval)
|
|
|
|
return bb
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bb *BlockBuilder) WithSECPMessageAndCode(bm *types.Message, code exitcode.ExitCode) *BlockBuilder {
|
|
|
|
secpMsg := bb.toSignedMessage(bm)
|
|
|
|
bb.secpMsgs = append(bb.secpMsgs, secpMsg)
|
|
|
|
bb.addResult(code, EmptyReturnValue)
|
|
|
|
return bb
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bb *BlockBuilder) WithSECPMessageAndRet(bm *types.Message, retval []byte) *BlockBuilder {
|
|
|
|
secpMsg := bb.toSignedMessage(bm)
|
|
|
|
bb.secpMsgs = append(bb.secpMsgs, secpMsg)
|
|
|
|
bb.addResult(exitcode.Ok, retval)
|
|
|
|
return bb
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bb *BlockBuilder) WithSECPMessageOk(bm *types.Message) *BlockBuilder {
|
|
|
|
secpMsg := bb.toSignedMessage(bm)
|
|
|
|
bb.secpMsgs = append(bb.secpMsgs, secpMsg)
|
|
|
|
bb.addResult(exitcode.Ok, EmptyReturnValue)
|
|
|
|
return bb
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bb *BlockBuilder) WithSECPMessageDropped(bm *types.Message) *BlockBuilder {
|
|
|
|
secpMsg := bb.toSignedMessage(bm)
|
|
|
|
bb.secpMsgs = append(bb.secpMsgs, secpMsg)
|
|
|
|
return bb
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bb *BlockBuilder) WithTicketCount(count int64) *BlockBuilder {
|
|
|
|
bb.ticketCount = count
|
|
|
|
return bb
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bb *BlockBuilder) toSignedMessage(m *types.Message) *types.SignedMessage {
|
|
|
|
from := m.From
|
|
|
|
if from.Protocol() == address.ID {
|
|
|
|
from = bb.TD.ActorPubKey(from)
|
|
|
|
}
|
|
|
|
if from.Protocol() != address.SECP256K1 {
|
2020-08-06 16:57:15 +00:00
|
|
|
T.Fatalf("Invalid address for SECP signature, address protocol: %v", from.Protocol())
|
2020-08-05 17:40:09 +00:00
|
|
|
}
|
|
|
|
raw, err := m.Serialize()
|
2020-08-06 16:57:15 +00:00
|
|
|
require.NoError(T, err)
|
2020-08-05 17:40:09 +00:00
|
|
|
|
|
|
|
sig, err := bb.TD.Wallet().Sign(from, raw)
|
2020-08-06 16:57:15 +00:00
|
|
|
require.NoError(T, err)
|
2020-08-05 17:40:09 +00:00
|
|
|
|
|
|
|
return &types.SignedMessage{
|
|
|
|
Message: *m,
|
|
|
|
Signature: sig,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bb *BlockBuilder) build() vtypes.BlockMessagesInfo {
|
|
|
|
return vtypes.BlockMessagesInfo{
|
|
|
|
BLSMessages: bb.blsMsgs,
|
|
|
|
SECPMessages: bb.secpMsgs,
|
|
|
|
Miner: bb.miner,
|
|
|
|
TicketCount: bb.ticketCount,
|
|
|
|
}
|
|
|
|
}
|