Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

title_clamp_filetest.gno

2.45 Kb · 64 lines
 1// PKGPATH: gno.land/r/test/titleclamp
 2package titleclamp
 3
 4// A proposal title is attacker-chosen (by a member) and is escaped on two
 5// pages: the proposal page and the list page. Escaping costs about 6,990 gas a
 6// byte, and the list page escapes one title per proposal shown, so an oversized
 7// title priced the whole list out of the query cap: five proposals with 90 KB
 8// titles cost 3,172,507,361 gas against a 3,000,000,000 cap. Clamping the title
 9// before it is escaped brings the same five to 66,871,916.
10//
11// Runs in its own realm because it creates proposals, and the unit tests in the
12// impl package assert hard-coded proposal ids against shared state.
13
14import (
15	"strings"
16	"testing"
17
18	"gno.land/r/gov/dao"
19	"gno.land/r/gov/dao/impl/v0"
20	"gno.land/r/gov/dao/memberstore/v0"
21)
22
23const user address = "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"
24
25func init(cur realm) {
26	memberstore.Get(0, cur).DeleteAll()
27	memberstore.Get(0, cur).SetTier(memberstore.T1)
28	memberstore.Get(0, cur).SetMember(memberstore.T1, user, memberstore.NewMember(3))
29	dao.UpdateImpl(cross(cur), dao.NewUpdateRequest(impl.NewGovDAO(), nil))
30}
31
32func main(cur realm) {
33	testing.SetOriginCaller(user)
34	testing.SetRealm(testing.NewUserRealm(user))
35
36	short := dao.MustCreateProposal(cross(cur), dao.NewProposalRequest(
37		"An ordinary title", "d", nil))
38	long := dao.MustCreateProposal(cross(cur), dao.NewProposalRequest(
39		strings.Repeat("t", 50000), "d", nil))
40
41	// An ordinary title is untouched. Real titles in examples/ are about 40
42	// bytes, so the bound never reaches them.
43	sout := dao.Render(cross(cur), short.String())
44	println("an ordinary title is left alone:",
45		strings.Contains(sout, "An ordinary title") && !strings.Contains(sout, "… truncated"))
46
47	// The proposal page cuts the title before escaping it. Asserting the marker
48	// rather than a length: escaping first and cutting second would also
49	// produce a short page, so length alone cannot tell the two apart.
50	pout := dao.Render(cross(cur), long.String())
51	println("the proposal page clamps a huge title:",
52		strings.Contains(pout, "… truncated") && len(pout) < 4000)
53
54	// The list page escapes one title per proposal it shows, so it is the page
55	// the bound actually protects.
56	lout := dao.Render(cross(cur), "")
57	println("the list page clamps it too:",
58		strings.Contains(lout, "… truncated") && len(lout) < 4000)
59}
60
61// Output:
62// an ordinary title is left alone: true
63// the proposal page clamps a huge title: true
64// the list page clamps it too: true